在 place/directly 更新列表中的迭代列表中 - 这应该有效吗?

In place/directly updating list of lists inside iteration - Should this be working?

我无意中注意到直接更新列表列表中的元素是可行的。

有很多关于更新列表列表的问答。然而我检查的所有答案都表明

但在下面的例子中我可以直接更新一个列表。

我找到的关于该主题的所有答案都相当陈旧,所以稍后是否将其添加到 python?

# COMPREHENSION ==================================
li = [
    ["spam1", "eggs1"],
    ["spam2", "eggs2"]
    ]

print("\nCOMPREHENSION ---------------")
print("INPUT", li)
li = [["new", l[1]] for l in li]
print("OUTPUT", li)

# INDEX ===========================================
li = [
    ["spam1", "eggs1"],
    ["spam2", "eggs2"]
    ]
print("\nINDEX -----------------")
print("INPUT", li)
for index, l in enumerate(li):
    li[index] = ["new", l[1]]
print("OUTPUT", li)

# IN PLACE ========================================
li = [
    ["spam1", "eggs1"],
    ["spam2", "eggs2"]
    ]
print("\nIN PLACE --------------")
print("INPUT", li, "       <<<<<<<<<<<<<")
for i in li:
    i[0] = f'new'
print("OUTPUT", li, "      <<<<<<<<<<<<<")

结果

COMPREHENSION ---------------
INPUT [['spam1', 'eggs1'], ['spam2', 'eggs2']]
OUTPUT [['new', 'eggs1'], ['new', 'eggs2']]

INDEX -----------------
INPUT [['spam1', 'eggs1'], ['spam2', 'eggs2']]
OUTPUT [['new', 'eggs1'], ['new', 'eggs2']]

IN PLACE --------------
INPUT [['spam1', 'eggs1'], ['spam2', 'eggs2']]        <<<<<<<<<<<<<
OUTPUT [['new', 'eggs1'], ['new', 'eggs2']]           <<<<<<<<<<<<<

这是有效的,因为您替换列表中的元素使用其索引,这对迭代没有影响。

禁止向正在迭代的列表中添加或删除元素,这是你永远不会做的。

一切都按预期进行。 你是对的,内部迭代元素只是被复制,所以改变复制的元素不会改变实际的列表。参见示例:

In [1]: x = [1,2,3,4,5,6,7,8]

In [2]: for a in x:
  ...:     if a ==2:
  ...:         a=3

In [3]: x
Out[3]: [1, 2, 3, 4, 5, 6, 7, 8]

当列表的一个元素实际上是一个列表时会发生什么?

In [4]: z = [[1,2],[3,4],[5,6]]

In [5]: for a in z:
  ...:     if a[0] ==3:
  ...:         a = [7,8]

In [6]: z
Out[6]: [[1, 2], [3, 4], [5, 6]]

您有一个分配给 a 的内部列表的副本,因此分配给 a 另一个列表不会更改外部列表 z

然而在迭代中实际复制的不是内部列表,而是a reference to it。所以 a 指向内部列表本身,而不是它的副本。您实际上可以修改此内部列表元素。喜欢这里:

In [8]: for a in z:
  ...:     if a[0] ==3:
  ...:         a[0] = 7

In [9]: z
Out[9]: [[1, 2], [7, 4], [5, 6]]

甚至 add/remove 个元素:

In [10]: for a in z:
   ...:     if a[0] ==1:
   ...:         a.append(22)


In [10]: z
Out[10]: [[1, 2, 22], [7, 4], [5, 6]]