简体   繁体   中英

Function to create dictionary with default values that can be either immutable or mutable

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 - ie 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?

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']

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM