【问题标题】:Why the value in dict changed total in python? [duplicate]为什么dict中的值在python中改变了总数? [复制]
【发布时间】:2015-11-05 02:29:53
【问题描述】:

最近做了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)没有这个问题?

【问题讨论】:

    标签: python dictionary


    【解决方案1】:

    简答:因为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
    

    【讨论】:

      【解决方案2】:

      如果您使用列表推导(替换 zip)或 for() 循环,您将不会使用同一个对象 3 次

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

      【讨论】:

        猜你喜欢
        • 2014-03-06
        • 2016-02-15
        • 2015-05-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-23
        相关资源
        最近更新 更多