如何在for循环中修改列表项?

262 投票
10 回答
433802 浏览
提问于 2025-04-16 06:27

我知道在循环遍历一个列表的时候,直接修改这个列表是不安全的。不过,假设我有一个字符串的列表,我想要去掉这些字符串两边的空格。那替换这些可变的值算不算是修改呢?


可以参考 为什么修改迭代变量不会影响后续的迭代? 了解相关问题:给迭代变量赋值并不会改变底层的序列,也不会影响后面的迭代。

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)

撰写回答