Python二维数组-更改元素

36

我有一个7x7的二维数组:

l=[[1, 1, 1, 1, 1, 1, 1],
  [1, 0, 2, 0, 0, 0, 1],
  [1, 0, 0, 0, 0, 0, 1],
  [1, 0, 0, 0, 0, 0, 1],
  [1, 0, 0, 0, 0, 0, 1],
  [1, 0, 0, 0, 0, 0, 1],
  [1, 1, 1, 1, 1, 1, 1]]

如您所见,l [1] [2] = 2。当我打印它时,元素被正确地打印出来,没有问题。但是,当我尝试将其从“2”更改为“3”或任何其他数字时,程序会更改该列中的所有元素(在这种情况下为第三列),除了第一个和最后一个元素。例如,如果我输入以下代码:

l[1][2]=5

然后打印这个二维数组,我得到了这个:

l=[[1, 1, 1, 1, 1, 1, 1],
  [1, 0, 5, 0, 0, 0, 1],
  [1, 0, 5, 0, 0, 0, 1],
  [1, 0, 5, 0, 0, 0, 1],
  [1, 0, 5, 0, 0, 0, 1],
  [1, 0, 5, 0, 0, 0, 1],
  [1, 1, 1, 1, 1, 1, 1]]

我选择任何元素都会发生这种情况。它不仅改变了该元素,还改变了整列的元素。 有人知道可能是什么问题吗?谢谢!


1
我无法重现它。你能否在Python解释器中自己运行所有这些代码?你使用的是哪个版本的Python? - László Papp
这没有任何意义,即使你有一个NumPy矩阵或多个引用相同的列表。您能否展示一个真实的解释器会话? - user2357112
2
你能展示一下你是如何实际构建列表的吗?我猜你可能不小心存储了同一个列表的多个引用。 - mgilson
@mgilson:很可能,但这仍然不会产生所示的输出。这可能是因为所显示的输出并不是 OP 实际获得的。 - user2357112
我注意到现在我在编写输出时犯了一个错误。第一行和最后一行保持不变,只有中间的行被更改。就像@mgilson建议的那样。我现在明白问题所在,并使用他的答案解决了它。谢谢。 - Joker
显示剩余2条评论
2个回答

66

虽然您所描述的行为(如您所描述的)是不可能的,但我会试着解决这个问题。

如果创建一个列表,则需要确保每个子列表都是不同的列表。例如:

a = []
b = [a, a]

我创建了一个列表,其中两个子列表都是完全相同的列表。如果我更改其中一个列表,它将同时显示在另一个列表中。例如:

>>> a = []
>>> b = [a, a]
>>> b[0].append(1)
>>> b
[[1], [1]]

你经常会看到使用 * 运算符初始化列表时出现这种行为:

a = [[None]*7]*7
例如。
>>> a = [[None]*7]*7
>>> a
[[None, None, None, None, None, None, None], [None, None, None, None, None, None, None], [None, None, None, None, None, None, None], [None, None, None, None, None, None, None], [None, None, None, None, None, None, None], [None, None, None, None, None, None, None], [None, None, None, None, None, None, None]]
>>> a[0][1] = 3
>>> a
[[None, 3, None, None, None, None, None], [None, 3, None, None, None, None, None], [None, 3, None, None, None, None, None], [None, 3, None, None, None, None, None], [None, 3, None, None, None, None, None], [None, 3, None, None, None, None, None], [None, 3, None, None, None, None, None]]

修复方法是不在外部列表中使用*7(内部列表可以使用,因为None是不可变的):

a = [[None]*7 for _ in range(7)]

e.g.:

>>> a = [[None]*7 for _ in range(7)]
>>> a[0][1] = 3
>>> a
[[None, 3, None, None, None, None, None], [None, None, None, None, None, None, None], [None, None, None, None, None, None, None], [None, None, None, None, None, None, None], [None, None, None, None, None, None, None], [None, None, None, None, None, None, None], [None, None, None, None, None, None, None]]

谢谢。那就是问题所在。我使用了您的建议解决了它。 - Joker
非常感谢!我浪费了3个小时来尝试调试这个问题。 - Samvit Agarwal
谢谢你的回答。 - MIARD
谢谢,但这是我不喜欢Python的原因之一。 - NightStorm

3
您的列表构造有误。
中间的项都指向同一个列表,因此更新其中一个会反映在其他项目上。
如果您展示用于构建列表的代码,我可以告诉您如何修复它。
或者,您也可以尝试...
l = [sublist[:] for sublist in l]

在开始修改之前,将所有列表解耦为新列表。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接