Python嵌套列表项不希望与父列表共享内存地址

Python嵌套列表项不希望与父列表共享内存地址,python,list,memory,Python,List,Memory,我在Python中遇到了一个奇怪的问题,我不能完全理解。我特别使用嵌套列表,一个包含两个列表的自定义列表类型对象,以便允许名为SuperList的负索引值模拟3D数组功能,以便像我这样组织块对象。所以基本上,列表[z][y][x]。列表[z]和列表[z][y]应该是列表对象,列表[z][y][x]应该是区块对象。最初设置为无,然后被覆盖 问题是:当输入的值是list[-2][-3][-4]时,所有内容都有自己的地址,但只要x从1增加到-3,那么list[-2][-3][-3],list[z][y

我在Python中遇到了一个奇怪的问题,我不能完全理解。我特别使用嵌套列表,一个包含两个列表的自定义列表类型对象,以便允许名为SuperList的负索引值模拟3D数组功能,以便像我这样组织块对象。所以基本上,列表[z][y][x]。列表[z]和列表[z][y]应该是列表对象,列表[z][y][x]应该是区块对象。最初设置为无,然后被覆盖

问题是:当输入的值是list[-2][-3][-4]时,所有内容都有自己的地址,但只要x从1增加到-3,那么list[-2][-3][-3],list[z][y]和list[z][y][x]就会突然指向完全相同的内存地址。我不明白为什么。显然,我不希望列表中某个单元格的值与列表本身具有相同的地址,但我对它发生的原因一无所知。下面是有问题的代码:它是一个函数,是一个世界对象的较小部分,它将self.chunk作为包含的超列表对象

def chunk_init(self):
        print ("World initialize")
        if self.chunk[0] == None:
            for zchunk in range(-self.z_range,self.z_range):
                    self.chunk[zchunk] = SuperList()
                    for ychunk in range(-self.y_range,self.y_range):
                        self.chunk[zchunk][ychunk] = SuperList()
                        for xchunk in range(-self.x_range,self.x_range):
                            chnk = self.generate_blank_chunk()
                            self.chunk[zchunk][ychunk][xchunk]= chnk
return
下面是SuperList对象的代码:

class SuperList():
    '''
    List type object that allows for negative values that also allows you
    to index into unappended values without throwing an error. Undefined values
    are set to None.
    '''

    def __init__(self, list_plus=[], list_minus=[]):
        self.list_plus = list_plus
        self.list_minus = list_minus

    def __setitem__(self,key,value):
        if key < 0:
            key = abs(key)
            if len(self.list_minus) < key+1:
                for i in range((key+1)-len(self.list_minus)):
                    self.list_minus.append(None)
                self.list_minus[key]=value
            else:
                self.list_minus[key]=value
        else:
            if len(self.list_plus) < key+1:
                for i in range((key+1)-len(self.list_plus)):
                    self.list_plus.append(None)
                self.list_plus[key]=value
            else:
                self.list_plus[key]=value
        return

    def __getitem__(self,key):
        if key < 0:
            key = abs(key)
            if len(self.list_minus) < key+1:
                for i in range((key+1)-len(self.list_minus)):
                    self.list_minus.append(None)
                self.list_minus[key]=None
                value = self.list_minus[key]
            else:
                value = self.list_minus[key]
        else:
            if len(self.list_plus) < key+1:
                for i in range((key+1)-len(self.list_plus)):
                    self.list_plus.append(None)
                self.list_plus[key]=None
                value = self.list_plus[key]
            else:
                value = self.list_plus[key]
        return value

如果有人能解释为什么会发生这种情况,我将非常感激。如果单元格最终与它们所在的列表共享相同的地址,我的嵌套列表将无法工作,因为这两个单元格都被设置为相同的值,而我突然在引用超级列表时引用了块。再次感谢。

这是因为您在参数中定义了可变默认值。这将导致每次创建SuperList实例时,都会重用定义为参数的可变列表,从而导致您看到的行为。你可以阅读更多关于这方面的内容

你需要把它改成这样

def __init__(self, list_plus=None, list_minus=None):
    self.list_plus = list_plus or []
    self.list_minus = list_minus or []

这样,每次创建类的新实例时,列表都会重新初始化。

这是因为您在参数中定义了一个可变的默认值。这将导致每次创建SuperList实例时,都会重用定义为参数的可变列表,从而导致您看到的行为。你可以阅读更多关于这方面的内容

你需要把它改成这样

def __init__(self, list_plus=None, list_minus=None):
    self.list_plus = list_plus or []
    self.list_minus = list_minus or []

这样,每次创建该类的新实例时,列表都会重新初始化。

成功了!非常感谢您的及时回复。我将进一步讨论可变和不可变,因为我肯定在它们的应用程序方面遗漏了一些细微差别。这很有效!非常感谢您的及时回复。我将进一步讨论可变和不可变的RTFM,因为我肯定在它们的应用程序方面遗漏了一些细微差别。