我正在尝试在主列表级别上对列表列表进行就地修改。但是,当我尝试修改迭代变量(在下面的示例中为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]]
答案 0 :(得分:4)
我在文档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)
答案 1 :(得分:0)
在Python中将值插入现有列表的通常方法是使用enumerate
,它可以让您一次遍历索引和值,然后使用索引来操作列表:
(1.0...2.0).random // 1.488899109647097
对于第二个示例,您将执行几乎相同的操作:
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
,并且由于您仅对它们进行了突变(不分配给它们),因此不需要{{1} }和索引
答案 2 :(得分:0)
如果你想保持简洁而不创建额外的变量,你也可以这样做:
c = [1,2,3]
print(id(c))
c[:] = [i+3 for i in c]
print(c, id(c))
输出:
2881750110600
2881750110600 [4, 5, 6]