当我尝试下面的列表创建时,我看到每个元素都引用了一个不同的对象。
>>> a = [1] * 7
>>> a[0] = 2
>>> a
Out[17]: [2, 1, 1, 1, 1, 1, 1]
但是,当我尝试使用词典创建以下列表时,我看到每个元素都引用同一个对象。
a = [{1:10, 2:20}] * 7
a[0][1] = 30
a
Out[20]:
[{1: 30, 2: 20},
{1: 30, 2: 20},
{1: 30, 2: 20},
{1: 30, 2: 20},
{1: 30, 2: 20},
{1: 30, 2: 20},
{1: 30, 2: 20}]
如何尽可能简单地创建第二个列表,但是使用元素副本而不是引用?
答案 0 :(得分:2)
>>> a = [{1:10, 2:20} for _ in range(7)]
>>> a[0][1] = 30
>>> a
[{1: 30, 2: 20}, {1: 10, 2: 20}, {1: 10, 2: 20}, {1: 10, 2: 20}, {1: 10, 2: 20}, {1: 10, 2: 20}, {1: 10, 2: 20}]
答案 1 :(得分:1)
实际上当你使用乘法创建一个列表时,python会创建一个包含相同内存地址的重复项的列表:
>>> a=[1]*7
>>> id(a[0])
40968536
>>> id(a[1])
40968536
>>> a = [{1:10, 2:20}]*7
>>> id(a[0])
140379402804592
>>> id(a[1])
140379402804592
但是当你想要改变像(数字,元组,字符串......)这样的不可变对象时,python会改变引用而不是对象!
当你改变一个可变对象时,python会改变对象本身,所以所有的条目都会改变。
因此,作为python 2中更有效的方法,您可以在列表理解中使用xrange
(xrange
返回生成器而不是列表)(在3 range
中)来创建列表:
>>> a = [{1:10, 2:20} for _ in xrange(7)]
>>> a
[{1: 10, 2: 20}, {1: 10, 2: 20}, {1: 10, 2: 20}, {1: 10, 2: 20}, {1: 10, 2: 20}, {1: 10, 2: 20}, {1: 10, 2: 20}]
>>> a[0][1]=0
>>> a
[{1: 0, 2: 20}, {1: 10, 2: 20}, {1: 10, 2: 20}, {1: 10, 2: 20}, {1: 10, 2: 20}, {1: 10, 2: 20}, {1: 10, 2: 20}]
>>> id(a[0])
140379402734400
>>> id(a[1])
140379402809424