Python列表追加导致奇怪的结果

时间:2013-06-26 09:29:15

标签: python list

我真的很奇怪。以下是示例代码:

class SomeClass(object):
    a = []
    b = []
    def __init__(self, *args, **kwargs):
        self.a = [(1,2), (3,4)]
        self.b = self.a
        self.a.append((5,6))
        print self.b

SomeClass()

打印输出[(1,2),(3,4),(5,6)],但为什么,为什么结果不是[(1,2),(3,4)]? 你知道我怎样才能在self.b中获得self.a的旧价值?

谢谢!

5 个答案:

答案 0 :(得分:7)

正如许多人已经提到的那样,你最终在相同的列表上有两个引用。通过另一个引用修改列表只需修改 列表。

以下是根据需要使事情更加清晰的说明:

Shared reference

  • 步骤“A”就在

    之后
    self.a = [(1,2), (3,4)]
    
  • 步骤“A”就在

    之后
    self.b = self.a
    
  • 步骤“C”就在

    之后
    self.a.append((5,6))
    

答案 1 :(得分:6)

您要将相同的列表分配给self.b,而不是副本。

如果您希望self.b引用该列表的副本,请使用list()或完整切片创建一个:

self.b = self.a[:]

self.b = list(self.a)

您可以从交互式口译员轻松测试:

>>> a = b = []  # two references to the same list
>>> a
[]
>>> a is b
True
>>> a.append(42)
>>> b
[42]
>>> b = a[:]  # create a copy
>>> a.append(3.14)
>>> a
[42, 3.14]
>>> b
[42]
>>> a is b
False

答案 2 :(得分:2)

self.b = self.a并非复制列表。它分配对该列表的引用,因此两个属性都指向同一个对象。如果您通过一个引用修改它,您也可以通过另一个参考来查看更改。

您可以使用copy.copy(the_list)获取正确的副本。或copy.deepcopy(the_list)如果您需要以下参考资料也已更新。

答案 3 :(得分:1)

python中的dicts在将它们分配给彼此时共享相​​同的内存空间。

有关详细信息,请参阅: http://henry.precheur.org/python/copy_list

答案 4 :(得分:1)

因为self.aself.b实际上是对同一列表对象的引用。

如果你想修改一个而不改变另一个,试试这个

class SomeClass(object):
    # a = []
    # b = [] # these two class member not necessary in this code
    def __init__(self, *args, **kwargs):
        self.a = [(1,2), (3,4)]
        self.b = list(self.a) # copy to a new list
        self.a.append((5,6))
        print self.b

SomeClass()