现在我知道在迭代循环期间修改列表是不安全的。但是,假设我有一个字符串列表,我想剥离字符串本身。替换可变值算作修改吗?


相关问题请参见for循环中python变量的作用域:给迭代变量赋值不会修改底层序列,也不会影响未来的迭代。


当前回答

在迭代列表时修改每个元素是可以的,只要不更改列表中的添加/删除元素。

你可以使用列表推导式:

l = ['a', ' list', 'of ', ' string ']
l = [item.strip() for item in l]

或者只做c风格的for循环:

for index, item in enumerate(l):
    l[index] = item.strip()

其他回答

在迭代列表时修改每个元素是可以的,只要不更改列表中的添加/删除元素。

你可以使用列表推导式:

l = ['a', ' list', 'of ', ' string ']
l = [item.strip() for item in l]

或者只做c风格的for循环:

for index, item in enumerate(l):
    l[index] = item.strip()

从你的问题中不清楚决定删除哪些字符串的标准是什么,但如果你有或可以列出你想删除的字符串,你可以做以下工作:

my_strings = ['a','b','c','d','e']
undesirable_strings = ['b','d']
for undesirable_string in undesirable_strings:
    for i in range(my_strings.count(undesirable_string)):
        my_strings.remove(undesirable_string)

my_strings变为['a', 'c', 'e']

因为下面的循环只修改了已经看到的元素,所以它被认为是可以接受的:

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

参见如何在迭代时从列表中删除项?。

你可以这样做:

a = [1,2,3,4,5]
b = [i**2 for i in a]

它被称为列表理解,让你更容易在列表中循环。

Ignacio Vazquez-Abrams给出的答案非常好。这个例子可以进一步说明。想象一下:

给出了一个包含两个向量的列表。 您希望遍历列表并反转每个数组的顺序。

假设你有:

v = np.array([1,2,3,4])
b = np.array([3,4,6])

for i in [v, b]:
    i = i[::-1]   # This command does not reverse the string.

print([v,b])

你会得到:

[array([1, 2, 3, 4]), array([3, 4, 6])]

另一方面,如果你这样做:

v = np.array([1,2,3,4])
b = np.array([3,4,6])

for i in [v, b]:
   i[:] = i[::-1]   # This command reverses the string.

print([v,b])

结果是:

[array([4, 3, 2, 1]), array([6, 4, 3])]