如何在for循环期间修改列表条目?

时间:2010-11-02 19:04:29

标签: python

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

9 个答案:

答案 0 :(得分:125)

由于下面的循环只修改已经看过的元素,因此可以认为是可接受的:

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]

因为它不需要创建临时列表并指定它来替换原始列表,但它确实需要更多的索引操作。

警告:虽然您可以通过这种方式修改条目,但您无法更改list中的项目数,而不会有遇到问题的风险。

这是我的意思的一个例子 - 从这一点删除一个条目搞砸索引:

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

答案 1 :(得分:106)

它被认为是糟糕的形式。如果需要保留对列表的现有引用,请使用列表推导,并使用切片分配。

a = [1, 3, 5]
b = a
a[:] = [x + 2 for x in a]
print(b)

答案 2 :(得分:16)

对于循环变体,我看起来比使用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

答案 3 :(得分:9)

在迭代列表时修改每个元素很好,只要不更改添加/删除元素到列表即可。

您可以使用列表理解:

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

或只是执行C-style for循环:

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

答案 4 :(得分:3)

如果您可以通过这种方式改变字符串,那么你不会改变列表的“内容”。但在Python中,它们并不可变。任何字符串操作都会返回一个新字符串。

如果您有一个您知道可变的对象列表,只要您不更改列表的实际内容,就可以执行此操作。

因此,您需要做某种地图。如果你使用生成器表达式,它[操作]将在你迭代时完成,你将节省内存。

答案 5 :(得分:3)

您可以这样做:

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

它被称为列表理解,以便您更容易在列表中循环。

答案 6 :(得分:1)

从您的问题中不清楚决定删除哪些字符串的标准是什么,但如果您有或可以列出要删除的字符串列表,则可以执行以下操作:

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更改为[&#39; a&#39;,&#39; c&#39;,&#39; e&#39;]

答案 7 :(得分:1)

Jemshit Iskenderov和Ignacio Vazquez-Abrams给出的答案确实很好。这个例子可以进一步说明:想象

a)给出了带有两个向量的列表;

b)您想遍历列表并反转每个数组的顺序

假设您有

package.json

您会得到

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([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])

答案 8 :(得分:0)

简而言之,在迭代相同列表的同时对列表进行修改。

list[:] = ["Modify the list" for each_element in list "Condition Check"]

示例:

list[:] = [list.remove(each_element) for each_element in list if each_element in ["data1", "data2"]]