在列表中硬拷贝字典
Hard copying dicts in a list
当我尝试创建以下列表时,我发现每个元素都引用不同的对象。
>>> 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 中更有效的方法,您可以使用 xrange
(xrange
return 生成器而不是列表)(在 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
当我尝试创建以下列表时,我发现每个元素都引用不同的对象。
>>> 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 中更有效的方法,您可以使用 xrange
(xrange
return 生成器而不是列表)(在 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