Dict inside defaultdict是通过键共享的 [英] Dict inside defaultdict being shared across keys
问题描述
>>> from collections import defaultdict
>>>> defaults = [('a',1),('b',{})]
>>> dd = defaultdict(lambda:dict(defaults))
>>> dd [0]
{'a':1,'b':{}}
>>> dd [1]
{'a':1,'b':{}}
>>> dd [0] ['b'] ['k'] ='v'
>>> dd
defaultdict(< function< lambda> at 0x7f4b3688b398>,{0:{'a':1,'b':{'k':'v'}},1:{'a' 1,'b':{'k':'v'}}})
>>> dd [1] ['b'] ['k'] ='v2'
>>> dd
defaultdict(< function< lambda> at 0x7f4b3688b398> {0:{'a':1,'b':{'k':'v2'}},1:{'a' 1,'b':{'k':'v2'}}})
对于这两个字典,code> v 已设置为 v2
。这是为什么?并且如何在没有太多性能开销的情况下更改此行为?
当您执行 dict(defaults)
你不会复制内部字典,只是再次引用它。所以当你改变这个字典时,你将会看到所有的变化。
你需要 deepcopy
这里避免这个问题:
import copy
from collections import defaultdict
defaults = {'a' :1,'b':{}}
dd = defaultdict(lambda:copy.deepcopy(defaults))
或者您不必在连续调用中使用相同的内部可变对象,因为不会重复引用 defaults
:
dd = defaultdict(lambda:{'a':1,'b':{}})
I have a dictionary inside a defaultdict. I noticed that the dictionary is being shared across keys and therefore it takes the values of the last write. How can I isolate those dictionaries?
>>> from collections import defaultdict
>>> defaults = [('a', 1), ('b', {})]
>>> dd = defaultdict(lambda: dict(defaults))
>>> dd[0]
{'a': 1, 'b': {}}
>>> dd[1]
{'a': 1, 'b': {}}
>>> dd[0]['b']['k'] = 'v'
>>> dd
defaultdict(<function <lambda> at 0x7f4b3688b398>, {0: {'a': 1, 'b': {'k': 'v'}}, 1:{'a': 1, 'b': {'k': 'v'}}})
>>> dd[1]['b']['k'] = 'v2'
>>> dd
defaultdict(<function <lambda> at 0x7f4b3688b398>, {0: {'a': 1, 'b': {'k': 'v2'}}, 1: {'a': 1, 'b': {'k': 'v2'}}})
Notice that v
was set to v2
for both dictionaries. Why is that? and how to change this behavior without much performance overhead?
When you do dict(defaults)
you're not copying the inner dictionary, just making another reference to it. So when you change that dictionary, you're going to see the change everywhere it's referenced.
You need deepcopy
here to avoid the problem:
import copy
from collections import defaultdict
defaults = {'a': 1, 'b': {}}
dd = defaultdict(lambda: copy.deepcopy(defaults))
Or you need to not use the same inner mutable objects in successive calls by not repeatedly referencing defaults
:
dd = defaultdict(lambda: {'a': 1, 'b': {}})
这篇关于Dict inside defaultdict是通过键共享的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!