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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4081217/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 14:08:52  来源:igfitidea点击:

How to modify list entries during for loop?

python

提问by Alex

Now I know that it is not safe to modify the list during an iterative looping. However, suppose I have a list of strings, and I want to strip the strings themselves. Does replacement of mutable values count as modification?

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

采纳答案by Ignacio Vazquez-Abrams

It's considered poor form. Use a list comprehension instead, with slice assignment if you need to retain existing references to the list.

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

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

回答by Skurmedel

No you wouldn't alter the "content" of the list, if you could mutate strings that way. But in Python they are not mutable. Any string operation returns a new string.

不,你不会改变列表的“内容”,如果你可以这样改变字符串。但在 Python 中,它们是不可变的。任何字符串操作都会返回一个新字符串。

If you had a list of objects you knew were mutable, you could do this as long as you don't change the actual contents of the list.

如果你有一个你知道是可变的对象列表,你可以这样做,只要你不改变列表的实际内容。

Thus you will need to do a map of some sort. If you use a generator expression it [the operation] will be done as you iterate and you will save memory.

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

回答by martineau

Since the loop below only modifies elements already seen, it would be considered acceptable:

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

a = ['a',' b', 'c ', ' d ']

for i, s in enumerate(a):
    a[i] = s.strip()

print(a) # -> ['a', 'b', 'c', 'd']

Which is different from:

与以下不同:

a[:] = [s.strip() for s in a]

in that it doesn't require the creation of a temporary list and an assignment of it to replace the original, although it does require more indexing operations.

因为它不需要创建临时列表和分配它来替换原始列表,尽管它确实需要更多的索引操作。

Caution:Although you can modifyentries this way, you can't change the number of items in the listwithout risking the chance of encountering problems.

注意:虽然您可以通过这种方式修改条目,但您不能在list不冒遇到问题的风险的情况下更改项目数。

Here's an example of what I mean—deleting an entry messes-up the indexing from that point on:

这是我的意思的一个例子 - 从那时起删除条目会弄乱索引:

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!

(The result is wrong because it didn't delete all the items it should have.)

(结果是错误的,因为它没有删除它应该拥有的所有项目。)

Update

更新

Since this is a fairly popular answer, here's how to effectively delete entries "in-place" (even though that's not exactly the question):

由于这是一个相当受欢迎的答案,以下是如何有效地“就地”删除条目(即使这不完全是问题):

b = ['a',' b', 'c ', ' d ']

b[:] = [entry for entry in b if entry.strip() == entry]

print(b)  # -> ['a']  # CORRECT

回答by Eugene Shatsky

One more for loop variant, looks cleaner to me than one with enumerate():

还有一个 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

回答by Jorge

It is not clear from your question what the criteria for deciding what strings to remove is, but if you have or can make a list of the strings that you want to remove , you could do the following:

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

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)

which changes my_strings to ['a', 'c', 'e']

将 my_strings 更改为 ['a', 'c', 'e']

回答by cizixs

Modifying each element while iterating a list is fine, as long as you do not change add/remove elements to list.

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

You can use list comprehension:

您可以使用列表理解:

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

or just do the C-stylefor loop:

或者只是做C-stylefor 循环:

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

回答by Nenoj

You can do something like this:

你可以这样做:

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

It's called a list comprehension, to make it easier for you to loop inside a list.

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

回答by Rafael Monteiro

The answer given by Jemshit Iskenderov and Ignacio Vazquez-Abrams is really good. It can be further illustrated with this example: imagine that

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

a) A list with two vectors is given to you;

a) 给你一个包含两个向量的列表;

b) you would like to traverse the list and reverse the order of each one of the arrays

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

Let's say you have

假设你有

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

You will get

你会得到

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

On the other hand, if you do

另一方面,如果你这样做

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

The result is

结果是

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

回答by siva balan

In short, to do modification on the list while iterating the same list.

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

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

example:

例子:

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