在python中保持列表独立并避免浅拷贝

在python中保持列表独立并避免浅拷贝,python,shallow-copy,Python,Shallow Copy,以下是我的伪代码: class foo(bar): def __init__(self, aList): bar.__init__(self, aList) self.initialList = aList def clock(self): modify(self.workingList) if(something): self.workingList = self.initialList

以下是我的伪代码:

class foo(bar):
    def __init__(self, aList):
        bar.__init__(self, aList)
        self.initialList = aList
    def clock(self):
        modify(self.workingList)
        if(something):
            self.workingList = self.initialList
        assert self.initialList == range(10)

class bar(object):
    def __init__(self, aList):
        self.workingList = aList
程序的正常操作如下所示:

a = range(10)
b = foo(a)
for i in xrange(10000):
    b.clock()
这不起作用,因为当我这样做的时候

self.workingList = self.initialList
self.workingList指向同一对象,而不是复制它。所以当我这么做的时候

modify(self.workingList)
它还修改了self.initialList,这意味着保持不变

我的解决办法是用

self.workingList = self.initialList

我甚至替换了

self.initialList = aList
与:

虽然我认为这在原则上应该有效,但在实践中并没有解决问题。我通过assert语句来验证这一点。我好像误解了一些python的语义。有人能解释一下吗

谢谢

编辑: 请注意,我理解deepcopy和shallowcopy之间的区别。这不是我的问题。我认为当我在类实例化/继承中使用它时,有些事情会变得一团糟。我正在脱机工作,以生成一段可以在此处提供的MCV代码。请继续关注该更新

更新:

我在MCVE中找到了C,下面是错误:

class bar(object):
    def __init__(self, aList):
        self.workingList = aList

class foo(bar):
    def __init__(self, aList):
        bar.__init__(self, aList)
        self.initialList = list(aList)
    def clock(self):
        self.workingList[2] = max(self.workingList[3], 2)
        #print self.workingList
        if(1):
            self.workingList = list(self.initialList)
        try:
                assert self.initialList == range(10)
        except:
                print self.initialList
                print self.workingList
                assert self.initialList == range(10)


a = range(10)
for i in xrange(10):
        b = foo(a)
        for j in xrange(100000):
                b.clock()

所以经过大量调试,我找到了这个bug的原因。一种可能的修复方法如下:

class bar(object):
    def __init__(self, aList):
        self.workingList = list(aList) #aList
原因是python按值传递对象引用。这是一个很好的解释

它与我的代码相关的方式是,每次我在foo.clock()中更改self.workingList时:

它实际上修改了aList指向的对象(在构造函数的外部!!),所以当我创建一个新的foo实例(aList)时,我向它传递了一个新的错误版本的aList。这太狡猾了


最棘手的事情是,重新分配self.workingList不会产生此错误(尽管在pass by reference中会产生此错误),但修改self.workingList会产生此错误,因为python会按值传递对象引用(所有这些都在中有详细说明)

您能提供一个建议解决方案的实际示例吗?因为你所做的应该复制一份清单。(顺便提一下,
list(aList)
是制作副本的一种更简单的方法。您可能还会在某些代码中看到
list[:]
。)此外,您是否更改了分配列表的所有实例,例如对
self.initialList
的引用?@GregHewgill-sure。什么样的例子会有帮助?还有,我疯了吗,或者我所做的足以将这些列表分开??这将非常有用。好的,让我离线处理。我将把它发布在这里,作为我问题的编辑/更新。谢谢本模块包含关于该主题的有用文档。
class bar(object):
    def __init__(self, aList):
        self.workingList = aList

class foo(bar):
    def __init__(self, aList):
        bar.__init__(self, aList)
        self.initialList = list(aList)
    def clock(self):
        self.workingList[2] = max(self.workingList[3], 2)
        #print self.workingList
        if(1):
            self.workingList = list(self.initialList)
        try:
                assert self.initialList == range(10)
        except:
                print self.initialList
                print self.workingList
                assert self.initialList == range(10)


a = range(10)
for i in xrange(10):
        b = foo(a)
        for j in xrange(100000):
                b.clock()
class bar(object):
    def __init__(self, aList):
        self.workingList = list(aList) #aList
modify(self.workingList)