硬拷贝列表中的字典



当我尝试创建以下列表时,我看到每个元素都引用不同的对象。

>>> 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}]

如何尽可能轻松地创建第二个列表,但使用元素副本而不是引用?

>>> 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}]
实际上,

当您使用乘法创建列表时,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中更有效的方法,您可以在列表推导中使用xrangexrange返回生成器而不是列表)(在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

最新更新