为什么 [defaultdict(int)] * 3 return 三个引用相同 object
Why does [defaultdict(int)] * 3 return three references to the same object
编辑:
为什么 [defaultdict(int)] * 3
return 三个引用同一个 object?
原标题
Unpack list of defaultdicts into variables has unexpected behavior in Python
将 defaultdict
类型的初始化列表解包到变量中似乎没有按我预期的方式工作。有谁知道为什么会这样(请参阅下面的代码片段)?我正在使用 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
完整片段:
>>> 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})
)
此问题基于问题 提出的主题。
问题与内存中的位置有关。一个简单的控制台测试表明:
> from collections import defaultdict
> l,m,p = [defaultdict(int), defaultdict(int), defaultdict(int)]
> id(l) == id(p)
False
> id(m) == id(p)
False
现在我们换个方式试试:
> l,m,p = [defaultdict(int)] * 3
> id(l) == id(p)
True
> id(m) == id(p)
True
在第一种情况下,您在内存中创建了三个独立的槽。第二,你在内存中创建一个点,然后创建两个额外的指针指向内存中的那个槽;因此当你更新一个时,它们都会改变,因为它们都指向内存中的同一个插槽。
更详细地说明了为什么某些数据类型会发生这种情况,而其他数据类型不会。 TL;DR - 小整数可以在同一个对象中,但为了优化而使用不同的指针。这就是为什么您可以 运行 id()
或 is
检查整数变量并查看它们指向同一个对象,但在修改每个对象时让它们独立运行。
编辑:
为什么 [defaultdict(int)] * 3
return 三个引用同一个 object?
原标题
Unpack list of defaultdicts into variables has unexpected behavior in Python
将 defaultdict
类型的初始化列表解包到变量中似乎没有按我预期的方式工作。有谁知道为什么会这样(请参阅下面的代码片段)?我正在使用 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
完整片段:
>>> 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})
)
此问题基于问题
问题与内存中的位置有关。一个简单的控制台测试表明:
> from collections import defaultdict
> l,m,p = [defaultdict(int), defaultdict(int), defaultdict(int)]
> id(l) == id(p)
False
> id(m) == id(p)
False
现在我们换个方式试试:
> l,m,p = [defaultdict(int)] * 3
> id(l) == id(p)
True
> id(m) == id(p)
True
在第一种情况下,您在内存中创建了三个独立的槽。第二,你在内存中创建一个点,然后创建两个额外的指针指向内存中的那个槽;因此当你更新一个时,它们都会改变,因为它们都指向内存中的同一个插槽。
id()
或 is
检查整数变量并查看它们指向同一个对象,但在修改每个对象时让它们独立运行。