Python 嵌套列表条目与父列表共享内存地址

标签 python list memory

我在 Python 中遇到了一个奇怪的问题,我不太明白。我正在使用嵌套列表(具体来说,包含两个列表的自定义列表类型对象,以便允许负索引值,名为“SuperList”)来模拟 3D 数组功能,以便为我正在做的一点 roguelike 组织 block 对象。基本上,列表[z][y][x]。 list[z] 和 list[z][y] 应该是列表对象,list[z][y][x] 应该是 block 对象。 (最初设置为None,后被覆盖)

问题是这样的:当输入的值是 list[-2][-3][-4] 时,所有内容都有自己的地址,因为它应该,但是一旦 x 将 1 增加到 -3,(所以 list [-2][-3][-3])、list[z][y] 和 list[z][y][x] 突然指向完全相同的内存地址。我不明白为什么。显然,我不希望列表中单元格的值与列表本身具有相同的地址,但我不太清楚为什么会发生这种情况。这是有问题的代码:(它是一个函数,是世界对象的较小部分,该世界对象具有 self.chunk 作为包含的 SuperList 对象。)

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

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

最佳答案

这是因为您在参数中定义了可变的默认值。这将导致您定义为参数的可变列表在您每次创建 SuperList 实例时被重用,从而导致您所目睹的行为。您可以阅读更多相关信息here .

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

您需要将其更改为类似这样的内容。

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

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

关于Python 嵌套列表条目与父列表共享内存地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58684601/

相关文章:

python - 具有 'linear' 和 'cubic' 的 Scipy griddata 产生 nan

python - 数据存储中的关系(一对多)

python - 将python字典转换为流程图

c++ - 理解 C++ 中指向 const 值的 const 指针

python - 将列表的列表转换为一个大列表python

memory - 非托管内存和托管内存

C++内存分配问题

python - 从在 Ubuntu 上运行的 Python 将文件保存在 Windows 文件夹中

python - 子函数的自定义打印函数 yield

c - C中的菱形数组排序