为啥附加到列表的值会动态变化?
Posted
技术标签:
【中文标题】为啥附加到列表的值会动态变化?【英文标题】:Why does value appended to list change dynamically?为什么附加到列表的值会动态变化? 【发布时间】:2022-01-08 01:09:55 【问题描述】:Python 版本:3.9.5
我的代码:
cells = [[i, i] for i in range(3)]
steps = []
for t in range(2):
for i in range(len(cells)):
xrand = random.randint(-5, 5)
yrand = random.randint(-5, 5)
cells[i][0] += xrand
cells[i][1] += yrand
steps.append(list(cells))
print(steps)
实际输出:
[[[3, 3], [2, 3], [6, 3]]]
[[[4, 7], [-3, 2], [8, 3]], [[4, 7], [-3, 2], [8, 3]]]
预期输出:
[[[3, 3], [2, 3], [6, 3]]]
[[[3, 3], [2, 3], [6, 3]], [[4, 7], [-3, 2], [8, 3]]]
我每次都在外部循环中更改列表 cells 的值,并将修改后的列表附加到 steps 列表中。正如您在输出中看到的那样,在第二次迭代中,cells 的第一个元素也被修改了,即使我只是将一个元素附加到列表中。
steps 的第一个元素是上一次迭代的cells 列表。但是在第二次迭代中,两个元素都会动态变化,即使我只是附加一个元素,所以第一个元素不应该受到影响。
为什么会发生这种情况以及如何克服?
【问题讨论】:
【参考方案1】:list(cells)
创建一个浅拷贝,因此修改cells
的可变内容也会改变浅拷贝的内容——或者说,浅拷贝的内容真的是同一个对象 作为cells
的内容。
你想要的是一个深拷贝:
import copy
cells = [[i, i] for i in range(3)]
steps = []
for t in range(2):
for i in range(len(cells)):
xrand = 1
yrand = 1
cells[i][0] += xrand
cells[i][1] += yrand
steps.append(copy.deepcopy(cells))
print(steps)
输出:
[[[1, 1], [2, 2], [3, 3]]]
[[[1, 1], [2, 2], [3, 3]], [[2, 2], [3, 3], [4, 4]]]
我已将 random.randint
部分替换为静态值,因此演示的输出更少……随机。
【讨论】:
【参考方案2】:列表被原地操作
这是因为列表是通过对磁盘上真实对象(存储位置)的引用来操作的。请参阅以下示例:
l = [2]
x = [l, l]
print(x)
>>> [[2], [2]]
l[0] = 4
print(x)
>>> [[4], [4]]
您可以通过使用新变量或 copy.deepcopy()
来克服这个问题
>>> import copy
>>> l = [2]
>>> x = [copy.deepcopy(l), l]
>>> print(x)
[[2], [2]]
>>> l[0] = 4
>>> print(x)
[[2], [4]]
【讨论】:
以上是关于为啥附加到列表的值会动态变化?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 GL_MAX_UNIFORM_BLOCK_SIZE 的值会发生变化?