为什么在Python中,使用n * [dict()]创建嵌套字典会导致相同的字典对象?
>>> d = [(111, 2222), (3333, 4444), (555, 666)]
>>> d
[(111, 2222), (3333, 4444), (555, 666)]
>>> x = len(d) * [dict().copy()][:]
>>> x
[{}, {}, {}]
>>> x[0]['x'] = 'u'
>>> x # All entries of x gets modified
[{'x': 'u'}, {'x': 'u'}, {'x': 'u'}]
>>>
>>> x = [dict(), dict(), dict()]
>>> x
[{}, {}, {}]
>>> x[0]['x'] = 'u'
>>> x # only one entry of x gets modified
[{'x': 'u'}, {}, {}]
>>>
答案 0 :(得分:5)
在x = len(d) * [dict().copy()][:]
中,dict
函数只运行一次。因此,所有三个词典都是相同的。如果你想要三个不同的词典,你需要运行三次,例如:
>>> x = [dict() for i in range(3)]
>>> x
[{}, {}, {}]
>>> x[0]['x'] = 'u'
>>> x
[{'x': 'u'}, {}, {}]
>>>
Python 创建列表后,才能将列表乘以。因此,当执行3 * [dict()]
时,首先评估dict
,然后执行乘法。 3*[int(1)]
也是如此,但注意到最初可能会让人感到困惑的差异:
>>> x = 3*[int(1)]
>>> x
[1, 1, 1]
>>> x[0] = 2
>>> x
[2, 1, 1]
从表面上看,这似乎与词典的乘法列表的情况不一致。这里的区别在于赋值语句x[0] = 2
不修改x[0]
的属性;它用新元素替换 x[0]
。因此,结果是不同的。
替换的概念也适用于词典。考虑:
>>> x = 3 * [dict()]
>>> x
[{}, {}, {}]
>>> x[0] = dict(x='u')
>>> x
[{'x': 'u'}, {}, {}]
即使x
中的三个词典开头都是一样的,语句x[0] = dict(x='u')
也会用新的词典替换第一个词典。