简体   繁体   English

在密钥中共享defaultdict中的Dict

[英]Dict inside defaultdict being shared across keys

I have a dictionary inside a defaultdict. 我在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. 请注意,两个字典的v都设置为v2 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. 当你执行dict(defaults)你不是要复制内部字典,只是另外引用它。 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: 你需要deepcopy来避免这个问题:

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 : 或者您不需要在连续调用中使用相同的内部可变对象,而不是重复引用defaults

dd = defaultdict(lambda: {'a': 1, 'b': {}})

Your values all contain references to the same object from defaults : you rebuild the outer dict, but not the inner one. 您的值都包含对defaults同一对象的引用:您重建外部字典,但不重建内部字典。 Just make a function that creates a new, separate object: 只需创建一个创建一个新的独立对象的函数:

def builder():
    return {'a': 1, 'b': {}}
dd = defaultdict(builder)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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