具有奇怪填充行为的python嵌套字典

时间:2017-04-18 16:37:13

标签: python dictionary

我在Python 2.7.12嵌套字典中看到了一个奇怪的行为,我不明白它为什么会发生。让我说我有这本词典:

list_1 = ['5', '10', '15', '30']
dict_1 = { i:[] for i in list_1 }

现在我创建一个这样的嵌套字典:

list_2 = ['a', 'b']
dict_2 = { i:dict_1 for i in list_2 }

和另一个嵌套的dict:

dict_3 = { i:{j:[] for j in list_1} for i in list_2 }

dict_3和dict_2在填写之前打印相同:

{'a': {'15': [], '10': [], '30': [], '5': []}, 'b': {'15': [], '10': [], '30': [], '5': []}}

但是当我填写词典时:

dict_2['a']['5'].append(1)
dict_3['a']['5'].append(1)

dict_2有一个我不想要的行为,在'a'和'b'中填充元素'5':

{'a': {'15': [], '10': [], '30': [], '5': [1]}, 'b': {'15': [], '10': [], '30': [], '5': [1]}}

dict_1具有我想要的行为,只填充'a'中的元素'5':

{'a': {'15': [], '10': [], '30': [], '5': [1]}, 'b': {'15': [], '10': [], '30': [], '5': []}}

我猜在dict_2中,嵌套的dict_1只是该字典的链接,而dict_3是一个真正的嵌套字典。那是对的吗 ?无论如何我发现python dicts的这种使用很容易引起误解,如果它不是bug,为什么在python中需要这种行为?

1 个答案:

答案 0 :(得分:2)

分配永远不会复制数据。在理解中看到作业有点困难。

dict_2 = {i:dict_1 for i in list_2}

相当于

dict_2 = {}
for i in list_2:
    dict_2[i] = dict_1 # the assignments I'm talking about

现在,您dict_2[i]引用了所有dict_1 i。没有数据被复制。内存中有一个值为{'15': [], '10': [], '30': [], '5': []}的字典,其名称为dict_1,但现在也由dict_2中的所有键引用。 (你可以在内存中拥有许多相同值的名称/引用。)

如果您想要字典的实际深层副本,请使用

>>> from copy import deepcopy
>>> dict_2 = {i:deepcopy(dict_1) for i in list_2}
>>> dict_2['a']['5'].append(1)
>>> dict_2
{'a': {'10': [], '30': [], '15': [], '5': [1]}, 'b': {'10': [], '30': [], '15': [], '5': []}}

同样的逻辑适用于dict_3