Reputation: 15
I have a function to create a dictionary with specific keys, which accepts a parameter to specify what each key's "default" value should be.
def new_dict(entrys_default=0):
my_dict = {}
for k in ['a', 'b', 'c']:
my_dict[k] = entrys_default
return my_dict
The issue is that when I call it with new_dict(entrys_default=[])
so that each entry in the dictionary is created with a new empty list as its value, when I then update one entry with returned_dict['a'].append(123)
then all entries are updated:
{'a': [123], 'b': [123], 'c': [123]}
This doesn't happen when using an integer, and I understand that it is because the entrys_default
is immutable when it is an integer, but is a reference to the same list when it is a list or dictionary.
I want to be able to have this function work the same as it does for integer parameters with lists and dictionaries as entrys_default
- i.e. each entry has its own list/dictionary - but want to keep the function flexible to also work for integers.
Can anyone please suggest the best way to go about this?
Upvotes: 0
Views: 104
Reputation: 531215
Do what collections.defaultdict
does; instead of taking an "example" default value, take a function that returns the desired default value. Then call that function and use its return value to initialize each element of the dict
being constructed.
def new_dict(make_default=int): # int() == 0
my_dict = {}
for k in ['a', 'b', 'c']:
my_dict[k] = make_default()
return my_dict
d = new_dict(list) # list() == [], but a distinct list each time it is called
d['a'].append(123)
assert d['a'] != d['b']
Upvotes: 2