0

I have really strange problem. Here is the sample code:

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()

Print outputs [(1, 2), (3, 4), (5, 6)], but why, why result isn't [(1,2), (3,4)] ? Do you know how can I have the old value of self.a in self.b?

Thank you!

4

5 回答 5

7

正如许多人已经提到的那样,您最终会在同一个列表中获得两个参考。通过一个引用或另一个引用修改列表只是修改列表

如果需要,这里有一个说明可以使事情更清楚:

共享参考

  • 步骤“A”紧随其后

    self.a = [(1,2), (3,4)]
    
  • 步骤“A”紧随其后

    self.b = self.a
    
  • 步骤“C”紧随其后

    self.a.append((5,6))
    
于 2013-06-26T09:50:19.983 回答
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
于 2013-06-26T09:30:50.947 回答
2

self.b = self.a没有复制列表。它将引用分配给该列表,因此两个属性都指向同一个对象。如果您通过一个参考对其进行修改,您也会通过另一个参考看到更改。

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

于 2013-06-26T09:31:15.627 回答
1

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

有关这方面的更多信息,请参阅: http ://henry.precheur.org/python/copy_list

于 2013-06-26T09:30:51.067 回答
1

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

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

类SomeClass(对象):
    # 一 = []
    # b = [] # 这两个类成员在这段代码中不是必需的
    def __init__(self, *args, **kwargs):
        self.a = [(1,2), (3,4)]
        self.b = list(self.a) # 复制到新列表
        self.a.append((5,6))
        打印自我.b

某类()
于 2013-06-26T09:32:29.933 回答