如何在for循环中修改列表项?
我知道在循环遍历一个列表的时候,直接修改这个列表是不安全的。不过,假设我有一个字符串的列表,我想要去掉这些字符串两边的空格。那替换这些可变的值算不算是修改呢?
可以参考 为什么修改迭代变量不会影响后续的迭代? 了解相关问题:给迭代变量赋值并不会改变底层的序列,也不会影响后面的迭代。
10 个回答
25
还有一种 for 循环的变体,我觉得比用 enumerate() 的那种看起来更简洁:
for idx in range(len(list)):
list[idx]=... # set a new value
# some other code which doesn't let you use a list comprehension
247
下面的循环只修改已经看到的元素,所以这样做是可以接受的:
a = ['a',' b', 'c ', ' d ']
for i, s in enumerate(a):
a[i] = s.strip()
print(a) # -> ['a', 'b', 'c', 'd']
这和下面的代码不同:
a[:] = [s.strip() for s in a]
因为它不需要创建一个临时列表来替换原来的列表,虽然这样做需要更多的索引操作。
注意:虽然你可以用这种方式来修改列表中的项,但如果想改变列表中的项目数量,就有可能遇到问题。
举个例子,删除一个项会导致后面的索引出错:
b = ['a', ' b', 'c ', ' d ']
for i, s in enumerate(b):
if s.strip() != b[i]: # leading or trailing whitespace?
del b[i]
print(b) # -> ['a', 'c '] # WRONG!
(结果是错误的,因为它没有删除所有应该删除的项。)
更新
因为这个回答挺受欢迎的,这里介绍一下如何有效地“就地”删除项(虽然这不是问题的核心):
b = ['a',' b', 'c ', ' d ']
b[:] = [entry for entry in b if entry.strip() == entry]
print(b) # -> ['a'] # CORRECT
可以参考这个链接:如何在遍历列表时删除项?.
176
这样做被认为是不太好的写法。建议使用列表推导式,如果你需要保留对原列表的引用,可以用切片赋值。
a = [1, 3, 5]
b = a
a[:] = [x + 2 for x in a]
print(b)