Implement two different approaches to add 5 to the end of the list [1, 2,
3, 4]
, one that modifies the original list and the other that does not.
# Modifies the list
a = [1, 2, 3, 4]
a.append(5)
# Does not modify the list (because list concatenation creates a new list)
a = [1, 2, 3, 4]
a + [5]
[PP Problem 8.9] Draw the memory model showing the effect of the following
statements (like the figure that would be produced by
values = [0, 1, 2]
values[1] = values
Check out the visualization at pythontutor.com showing the “points to” relationships. Notice the recursive structure that is created when an item in the list points to itself. This is legal in Python, but likely not a good idea.
What is the value of the list a
after this code executes?
def mystery(a_list):
a_list.sort()
return a_list[0]
a = [3, 7, 2, 9, 1]
print("Result:", mystery(a))
a
will be sorted, i.e. [1, 2, 3, 7, 9]
because a
and a_list
are
aliased.
What is the value of the list a
after this code executes?
def mystery(a_list):
a_list = sorted(a_list)
return a_list[0]
a = [3, 7, 2, 9, 1]
print("Result:", mystery(a))
a
will be unchanged, i.e. [3, 7, 2, 9, 1]
because sorted
returns a
new list.
What is the value of the list a
after this code executes?
def mystery(a_list):
a_list = a_list[::]
a_list.sort()
a_list[1].append(2)
return a_list[0][0]
a = [[3], [7], [2], [9], [1]]
print("Result:", mystery(a))
The first line of mystery
makes a “deepish” copy of the list, and sorts
that copy. Thus the original list pointed to by a
does not change.
However, that copy is only “one level” deep. Thus modifications to the
nested lists are still visible via a
. The value of a
is then [[3],
[7], [2, 2], [9], [1]]
, reflecting appending the value 2 to the nested
list at index 1.
Draw the Python memory model after this code executed (like the figure that
would be produced by
a = [1, 2, [3, 4], 5]
b = a[:]
a[2].append(4)
Check out the visualization at pythontutor.com. Notice that the slice
has created a single-level copy of a
, but that both a
and b
point to
the same nested lists and so the append
is visible via both a
and b
.
What is the result of the following expressions?
a. {2, 3, 5, 6, 7, 8}
b. {5, 7}
c. {2, 3}
d. {2, 3, 6, 8}
e. False
f. True
[PP Problem 11.1] Write a function named find_dups
that takes a list of
integers as its input argument and returns a set of those integers that
occur two or more times in the list.
def find_dups(int_list):
"""
Return set of duplicate values
Args:
int_list: List of integers
Returns:
Set of duplicate integers
"""
seen = set()
repeats = set()
for num in int_list:
if num in seen:
# We've seen num before, so it's a
# repeat and we want to return it eventually
repeats.add(num)
else:
# This is a new num so add it to the
# set of those we've seen
seen.add(num)
return repeats
What is the value of the dictionary e
after this code executes?
{2: 2, 6: 4, 4: 2}
[PP Problem 11.4] The keys in a dictionary are guaranteed to be unique, but
the values are not. Write a function called count_values
that takes a
single dictionary as an argument and returns the number of distinct values
it contains. Given the input {'red': 1, 'green': 1, 'blue': 2}
, for
example, it should return 2
.
def count_values(some_dict):
"""
Counts unique values in dictionary
Args:
some_dict: dictionary
Returns:
Integer count of duplicated values
"""
value_set = set()
for val in some_dict.values():
value_set.add(val)
return len(value_set)
# An alternate implentation that takes advantage of the set constructor
def count_values2(some_dict):
"""
Counts unique values in dictionary
Args:
some_dict: dictionary
Returns:
Integer count of duplicated values
"""
return len(set(some_dict.values()))
[PP Problem 11.5] After doing a series of experiments, you have compiled a
dictionary showing the probability of detecting certain kinds of subatomic
particles. The particles’ names are the dictionary’s keys, and the
probabilities are the values: {'neutron': 0.55, 'proton': 0.21, 'meson':
0.03, 'muon': 0.07, 'neutrino': 0.14}
. Write a function that takes a single
dictionary of this kind as input and returns the particle that is least
likely to be observed. Given the dictionary shown earlier, for example, the
function would return ‘meson’.
def min_key(some_dict):
"""
Returns key with smallest value (assuming all values are probabilities)
Args:
some_dict: Dictionary with comparable values
Returns:
Key
"""
# Set min_key to be a placeholder in case dictionary is empty
min_key = None
# We don't need to initialize min_value before loop since
# we are guaranteed to initialize it before use
for key in some_dict:
if min_key == None or some_dict[key] < min_value:
min_key = key
min_value = some_dict[key]
return min_key
You want to determine if all of the keys of a dictionary are integers. Write
a function named all_ints
that takes a dictionary as a parameter and
returns True
if all the keys are integers and False
otherwise. For example:
>>> all_ints({ 1: 2, 2: "a" })
True
>>> all_ints({ 1: 2, 2: "a", "c": 3 })
False
As a hint, recall that you can use the type
function to determine the type of a
value, and that you can perform equality comparisons on those types, e.g.
>>> type(1) == int
True
>>> type(1) == float
False
>>> type("a") == int
False
def all_ints(dictionary):
# Iterate through all keys in the dictionary
for key in dictionary.keys():
if type(key) != int:
# As soon we we find one non-int, then we know the
# function should return False (and we can stop)
return False
# At this point we have iterated through all the keys and all must
# have been integers (or we would have returned False), and thus we
# know we can return True
return True