Dict inside defaultdict是通过键共享的 [英] Dict inside defaultdict being shared across keys

查看:156
本文介绍了Dict inside defaultdict是通过键共享的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在一个defaultdict里面有一个字典。我注意到字典是通过键共享的,因此它需要最后写入的值。如何隔离这些字典?

 >>> 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆