2013-06-26 20 views
0

我真的很奇怪的问题。下面是示例代码:Python列表追加导致奇怪的结果

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的旧值?

谢谢!

+1

原因是b点到,当你改变,你就改变B中也 – matino

回答

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 
+0

我想补充的第二种方法self.b =名单(自我。 a),请将此添加到答案中。 –

+0

谢谢!解决了! – user232343

1

python中的词典共享相同的内存s当你将它们分配给彼此时

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

+2

这些是列表,而不是字典。列表do * not *有一个'.copy()'方法。 –

+0

我的错误我将编辑我的答案 – zidsal

2

self.b = self.a不复制列表。它将参考分配给该列表,因此两个属性都指向同一个对象。如果您通过一个参考文件修改它,您也会通过另一个参考文件查看更改。

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

+1

列表对象没有'.copy'方法 – Blender

+0

@Blender我想他的意思是copy.copy(listname) –

+0

是的,抱歉可以更明确。现在编辑。 – viraptor

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

正如许多人已经提到这个问题,最终不得不在相同名单上引用。通过一个引用修改列表只是修改列表列表。

这里有一个例子,以使事情更清楚,如果需要:

Shared reference

  • 步骤 “A” 是刚过

    self.a = [(1,2), (3,4)] 
    
  • 步骤 “A” 是刚过

    self.b = self.a 
    
  • 步骤“C”是刚过

    self.a.append((5,6)) 
    
+0

你是如何生成这些图像的? –

+1

@AshwiniChaudhary Inkscape ... –