就地修改 Python 列表

新手上路,请多包涵

我正在尝试在主列表级别对列表列表进行就地修改。但是,当我尝试修改迭代变量(下例中的 row )时,它似乎创建了一个指向它的新指针而不是修改它。


我的问题的最小例子。

 c = [1,2,3]
for x in c:
    x = x + 3
print(c) #returns [1,2,3], expected [4,5,6]

上面的例子是我的问题的一个简单例子。有没有办法就地修改 x 元素,并让更改出现在C中?


我的问题的不那么简单的例子。我正在将所有 0 切换为 1,反之亦然。

 A =  [[1,1,0],
      [1,0,1],
      [0,0,0]]
for row in A:
    row = list(map(lambda val: 1 - val, row))
print(A)

预期的

A = [[0,0,1],
     [0,1,0],
     [1,1,1]]

回来

A = [[1,1,0],
     [1,0,1],
     [0,0,0]]


更新:到目前为止很好的答案。我对迭代变量( row 在第二个示例中)如何链接到可迭代变量( A 在第二个示例中)感兴趣。

如果我执行以下操作,反转 A 的每个子列表,它就可以完美运行。

为什么下面的例子,我修改了迭代变量,但是上面的例子没有?

 A =  [[1,1,0],
  [1,0,1],
  [0,0,0]]

for row in A:
    row.reverse()
print(A)

#returns, as expected
A = [[0, 1, 1],
     [1, 0, 1],
     [0, 0, 0]]

原文由 Alexander 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 460
2 个回答

我在文档中找到了这个: https ://docs.python.org/3/tutorial/controlflow.html#for

Python 的 for 语句按照它们在序列中出现的顺序迭代任何序列(列表或字符串)的项目。

如果您需要修改在循环内迭代的序列(例如复制选定的项目),建议您先制作一个副本。遍历一个序列并不会隐式地创建一个副本。

我的第一个反应是错误的,当遍历列表时,它会返回该列表中的实际项目。但是,似乎无法在迭代时直接编辑它们。这就是为什么遍历列表长度的整数有效的原因。

至于为什么 .reverse() 函数起作用,我认为这是因为它影响的是列表而不是值。我尝试在非列表数据类型上使用类似的内置函数,例如 .replace() 在字符串上,但没有效果。

我尝试过的所有其他列表函数都有效: .append().remove().reverse() 如您所示。我不确定这是为什么,但我希望它能更清楚地说明您可以在 for 循环中做什么。

回答下面的旧问题:

您使用 for 循环的方式不会影响实际列表,只会影响遍历列表的临时变量。有几种方法可以解决这个问题。您可以计算到列表的长度并直接修改列表,而不是遍历每个元素。

 c = [1,2,3]
for n in range(len(c)):
    c[n] += 3
print(c)

您还可以使用 enumerate() 函数遍历计数器和列表项。

 c = [1,2,3]
for n, x in enumerate(c):
    c[n] = x + 3
print(c)

在这种情况下,n 是一个计数器,x 是列表中的项目。

最后,您可以使用列表理解生成一个新列表,其中一行包含所需的差异。

 c = [1, 2, 3]
d = [x + 3 for x in c]
print(d)

原文由 Aeolus 发布,翻译遵循 CC BY-SA 4.0 许可协议

在 Python 中将值插入现有列表的常用方法是使用 enumerate 这让您可以同时遍历索引和值 - 然后使用索引来操作列表:

 c = [1,2,3]
for index, value in enumerate(c):
    c[index] = value + 3

对于你的第二个例子,你会做几乎相同的事情:

 A =  [[1,1,0],
  [1,0,1],
  [0,0,0]]

for row in A:
    for index, val in row:
        row[index] = 0 if val > 0 else 1

在第二个示例中,列表对象 A 成为循环变量 row 因为你只是改变它们(而不是分配给它们)你不需要 enumerate 和索引

原文由 theodox 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏