为什么dict中的值在python中改变了总数?

时间:2015-11-05 02:29:53

标签: python dictionary

最近我做了2次实验:

(1):

>>> a = dict(zip([1,2,3],[4]*3))
>>> a
{1: 4, 2: 4, 3: 4}

>>> a[1] = 111    
>>> a
{1: 111, 2: 4, 3: 4}

(2):

>>> a = dict(zip([1,2,3],[{'a':True,'b':True}]*3))
>>> a
{1: {'a': True, 'b': True}, 
 2: {'a': True, 'b': True}, 
 3: {'a': True, 'b': True}}

>>> a[1]['a']=False  # Here I changed the value of a[1]['a'] from True to False    
>>> a
{1: {'a': False, 'b': True}, 
 2: {'a': False, 'b': True}, 
 3: {'a': False, 'b': True}}     #all 'a' value changed to False.

为什么(2)中的这个问题发生了?为什么(1)没有这个问题?

2 个答案:

答案 0 :(得分:7)

简短回答:因为dict个对象是可变的,int个对象是不可变的。

<强>详细信息:

查看[{'a': True, 'b': True}] * 3

使用

>>> l = [{}] * 3

创建列表,其中包含对同一对象的引用3次。

>>> id(l[0])
139685186829320
>>> id(l[1])
139685186829320
>>> id(l[2])
139685186829320

因此,当您更改其中一个时,您将全部更改(以防可变对象)。

如果您想要不同词典的列表,可以使用:

>>> l = [{} for x in range(3)]
>>> id(l[0])
139685161766216
>>> id(l[1])
139685161766536
>>> id(l[2])
139685161766600

在你的情况下它应该是这样的:

a = dict(zip([1, 2, 3], [{'a': True, 'b': True} for i in range(3)]))

对于不可变对象,它是不同的

您无法更改不可变对象。在您更改不可变对象的任何地方,都会创建一个新对象。

因此,当您尝试在列表中更改不可变对象时,会创建一个新对象:

>>> l = [1] * 3

>>> id(l[0])
139685185487008
>>> id(l[1])
139685185487008
>>> id(l[2])
139685185487008

>>> l[0] = 2

>>> id(l[0])
139685185487040  # new object created instead of old object being modified
>>> id(l[1])
139685185487008
>>> id(l[2])
139685185487008

答案 1 :(得分:0)

如果使用list comprehension(替换为zip)或for()循环,则不会使用同一个对象3次

a = {ctr:{'a':True,'b':True} for ctr in range(1, 4)}
print a
a[1]['a']=False
print a