Python如何多次复制列表,修改其中一个时其余副本保持不变?
问题原因
list.copy()执行的是浅拷贝,对于嵌套列表结构,仅会复制最外层列表的容器,内层嵌套的所有子列表仍会共享原对象的引用。
你当前代码中cubes是二维列表,cubes.copy()生成的新列表,每个元素仍指向原cubes中对应的子列表。当你循环执行6次拷贝后,sides中6个元素虽然是独立的外层列表,但它们内部的所有子列表都和原cubes的子列表是同一个对象。所以修改任意side[i][j][k],所有sides中对应位置的数值都会同步变更。
你可以通过打印sides[0][0] is sides[1][0]验证,输出为True即可证明两个子列表是同一个引用对象。
修复方案
方案1:使用深拷贝
导入标准库copy的deepcopy方法,它会递归复制所有层级的嵌套对象,彻底切断引用共享:
import copy # 把原来的拷贝逻辑替换为 for i in range(6): sides[i] = copy.deepcopy(cubes)
方案2:更优的原生实现(推荐)
你可以直接按业务逻辑生成sides,无需先拷贝全量cubes再逐个修改,既避免了深浅拷贝的坑,逻辑也更清晰:
原cubes每个元素的结构为[x_min, y_min, z_min, x_max, y_max, z_max],6个面对应分别取x/y/z轴的最大/最小值替换对应坐标即可,实现如下:
def sideArray(): cubes = [[-4, 8, -4, 4, 16, 4], [-4, -4, -2, 4, 8, 2], [-8, -4, -2, -4, 8, 2], [4, -4, -2, 8, 8, 2], [-4, -16, -2, 0, -4, 2], [0, -16, -2, 4, -4, 2]] sides = [] for face_idx in range(6): coord_pos = face_idx % 3 val_idx = face_idx + 3 if face_idx < 3 else face_idx - 3 current_face = [] for cube in cubes: cube_face = cube.copy() cube_face[coord_pos] = cube[val_idx] current_face.append(cube_face) sides.append(current_face) return sides if __name__ == '__main__': print(sideArray())
这个实现只在需要的时候拷贝单个立方体的一维列表,性能更高,也不会出现引用共享的问题。
内容的提问来源于stack exchange,提问作者Natan
相关产品推荐
相关产品推荐

