【发布时间】:2021-12-02 03:46:47
【问题描述】:
编辑:
为什么[defaultdict(int)] * 3 会返回对同一个对象的三个引用?
原标题
将 defaultdicts 列表解包到变量中在 Python 中有意外行为
将defaultdict 类型的初始化列表解压缩到变量中似乎并不像我期望的那样工作。有谁知道为什么会这样(参见下面的代码 sn-ps)?我正在使用Python 3.9.1。
# Equivalent behavior - works OK
a,b,c = [int(), int(), int()]
d,e,f = [int()] * 3
# Expected equivalent behavior - BEHAVES DIFFERENTLY
l,m,p = [defaultdict(int), defaultdict(int), defaultdict(int)]
q,r,s = [defaultdict(int)] * 3
完整的 sn-p:
>>> a,b,c = [int(), int(), int()]
>>> a+=4; b+=2; c+=7
>>> a,b,c
(4, 2, 7)
>>> d,e,f = [int()] * 3
>>> d+=11; e+=8; f+= 41
>>> d,e,f
(11, 8, 41)
>>> from collections import defaultdict
>>> l,m,p = [defaultdict(int), defaultdict(int), defaultdict(int)]
>>> l['a']+=1; m['b']+=2; m['c']+=3;
>>> l,m,p
(
defaultdict(<class 'int'>, {'a': 1}),
defaultdict(<class 'int'>, {'b': 2, 'c': 3}),
defaultdict(<class 'int'>, {})
)
>>> q,r,s = [defaultdict(int)] * 3
>>> q['a']+=111; r['b']+=222; m['c']+=333;
>>> q,r,s
(
defaultdict(<class 'int'>, {'a': 111, 'b': 222}),
defaultdict(<class 'int'>, {'a': 111, 'b': 222}),
defaultdict(<class 'int'>, {'a': 111, 'b': 222})
)
这个问题是基于问题"Unpack list to variables"提出的主题。
【问题讨论】:
-
您到底在说什么意外行为?
[defaultdict(int)] * 3会生成一个列表,其中包含三个对同一个 defaultdict 的引用? -
谢谢,这正是我的问题。我更新了标题以反映这一点。
-
这基本上是完全相同的问题as described here。在这种情况下的修复类似于
q,r,s = [defaultdict(int) for _ in range(3)] -
第一个代码 sn-p 上的 cmets 错误:
[int()] * 3的行为与[defaultdict(int)] * 3完全相同!在这两种情况下,相同的引用被复制了 3 次。自己看看:[id(x) for x in [d, e, f]]. -
@LiamFiddler 是的,我没有质疑这一点。我要说的是,声明的行为对于 int 和 defaultdicts 是相同的,这与第一个代码 sn-p 中的 OP 的 cmets 相反。因为……它是。
标签: python python-3.x initialization defaultdict unpack