python - 元素(数组) "multiplication"vs. 列表理解初始化

标签 python arrays

<分区>

关于问题:

How to initialize a two-dimensional array in Python?

在处理二维数组时,我发现以某种方式对其进行初始化会产生意想不到的结果。我想了解以这两种方式初始化 8x8 网格的区别:

>>> a =  [[1]*8]*8
>>> a
[[1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1], \
 [1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1], \
 [1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1], \
 [1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1]]

对比

>>> A =  [[1 for i in range(8)] for j in range(8)]
>>> A
[[1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1], \
 [1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1], \
 [1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1], \
 [1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1]]

意想不到的结果是,使用索引 [0-6][x] 访问的任何元素都将指向 [7][x] 中的最后一行。数组在解释器中看起来 相同,因此我很困惑。第一种方法有什么问题?

如果相关,这些数组包含对代表棋盘方 block 的 GTK EventBoxes 的引用。将初始化方法更改为列表理解方法后,方 block 可以正确响应预期的悬停和单击事件。

最佳答案

当您使用 a = [[1]*8]*8 创建二维数组时,* 运算符会创建 8 个对同一对象的引用。因此,[1]*8 意味着创建一个大小为 8 的数组,其中所有 8 个元素都是相同的对象(相同的引用)。由于所有元素都是相同的引用更新值,该引用点将更改数组中每个元素的值。

使用列表理解 A = [[1 for i in range(8)] for j in range(8)] 确保二维数组中的每个元素都被唯一引用。这避免了您在所有元素同时更新时看到的错误行为。

关于python - 元素(数组) "multiplication"vs. 列表理解初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18933257/

相关文章:

javascript - 获取屏幕大小以选择匹配的标题图片

javascript - 在没有拼接功能的情况下从数组中删除项目

c++ - 不使用指针遍历 C 风格的数组

Python-如何比较字符串中两个列表的内容

python - 检查是否可以分词

c - 警告 : assignment from incompatible pointer type for a 2D array pointer

javascript - 使用 jQuery 将 JS 对象转换为数组

python - 为什么使用: from sub-package import item statement doesn't work?

python - 在 R [Inf] 和 Python 中处理大量数字

python - 尝试通过python直播YouTube