如何在Python中删除for循环中的列表元素?(复制)

时间:2021-10-14 21:41:27

This question already has an answer here:

这个问题已经有了答案:

I have a list

我有一个列表

a = ["a", "b", "c", "d", "e"]

I want to remove elements in this list in a for loop like below:

我想在for循环中删除这个列表中的元素,如下所示:

for item in a:
    print item
    a.remove(item)

But it doesn't work. What can I do?

但它不工作。我能做什么?

7 个解决方案

#1


70  

You are not permitted to remove elements from the list while iterating over it using a for loop.

在使用for循环对列表进行迭代时,不允许从列表中删除元素。

The best way to rewrite the code depends on what it is you're trying to do.

重写代码的最佳方式取决于您要做什么。

For example, your code is equivalent to:

例如,您的代码相当于:

for item in a:
  print item
a[:] = []

Alternatively, you could use a while loop:

您也可以使用while循环:

while a:
  print a.pop(0)

I'm trying to remove items if they match a condition. Then I go to next item.

如果它们符合条件,我就试着删除它们。然后我进入下一项。

You could copy every element that does match the condition into a second list:

你可以将所有符合条件的元素复制到第二个列表中:

result = []
for item in a:
  if condition:
    result.append(item)
a = result

Alternatively, you could use filter or a list comprehension and assign the result back to a:

您也可以使用过滤器或列表理解,并将结果返回给a:

a = filter(lambda item:... , a)

or

a = [item for item in a if ...]

where ... stands for the condition that you need to check.

在那里……表示您需要检查的条件。

#2


32  

Iterate through a copy of the list:

迭代列表的副本:

>>> a = ["a", "b", "c", "d", "e"]
>>> for item in a[:]:
    print item
    if item == "b":
        a.remove(item)

a
b
c
d
e
>>> print a
['a', 'c', 'd', 'e']

#3


9  

As other answers have said, the best way to do this involves making a new list - either iterate over a copy, or construct a list with only the elements you want and assign it back to the same variable. The difference between these depends on your use case, since they affect other variables for the original list differently (or, rather, the first affects them, the second doesn't).

正如其他答案所言,实现此目的的最佳方法是创建一个新列表——要么在副本上迭代,要么构造一个只包含您想要的元素的列表,并将其分配回相同的变量。它们之间的差异取决于您的用例,因为它们对原始列表的其他变量有不同的影响(或者,更确切地说,第一个影响它们,第二个不影响)。

If a copy isn't an option for some reason, you do have one other option that relies on an understanding of why modifying a list you're iterating breaks. List iteration works by keeping track of an index, incrementing it each time around the loop until it falls off the end of the list. So, if you remove at (or before) the current index, everything from that point until the end shifts one spot to the left. But the iterator doesn't know about this, and effectively skips the next element since it is now at the current index rather than the next one. However, removing things that are after the current index doesn't affect things.

如果出于某种原因,副本不是选项,那么您还有一个选项,它依赖于您对为什么要修改列表进行迭代的理解。列表迭代的工作方式是跟踪一个索引,每次循环递增一个索引,直到它从列表的末尾消失。所以,如果你在当前索引处(或之前)移除,从该点到末端都向左移动一个点。但是迭代器不知道这一点,并且有效地跳过了下一个元素,因为它现在是在当前索引中,而不是下一个元素。但是,删除当前索引之后的内容不会影响到其他内容。

This implies that if you iterate the list back to front, if you remove an item at the current index, everything to it's right shifts left - but that doesn't matter, since you've already dealt with all the elements to the right of the current position, and you're moving left - the next element to the left is unaffected by the change, and so the iterator gives you the element you expect.

这意味着如果你回到前面迭代列表,如果删除一个项目目前的指数,它的一切左移右——但这并不重要,因为你已经处理的所有元素的当前位置,和你走左,下一个元素左边是变化的影响,因此,迭代器给你你希望的元素。

TL;DR:

TL;博士:

>>> a = list(range(5))
>>> for b in reversed(a):
    if b == 3:
        a.remove(b)
>>> a
[0, 1, 2, 4]

However, making a copy is usually better in terms of making your code easy to read. I only mention this possibility for sake of completeness.

然而,复制代码通常更容易阅读。为了完整起见,我只提到这种可能性。

#4


2  

How about creating a new list and adding elements you want to that new list. You cannot remove elements while iterating through a list

如何创建一个新的列表并添加您想要的元素到新的列表中呢?在遍历列表时不能删除元素。

#5


1  

import copy

a = ["a", "b", "c", "d", "e"]

b = copy.copy(a)

for item in a:
    print item
    b.remove(item)
a = copy.copy(b)

Works: to avoid changing the list you are iterating on, you make a copy of a, iterate over it and remove the items from b. Then you copy b (the altered copy) back to a.

工作:为了避免更改正在迭代的列表,您将复制a,对其进行迭代,并从b中删除项。然后将b(已修改的副本)复制回a。

#6


0  

Probably a bit late to answer this but I just found this thread and I had created my own code for it previously...

回答这个问题可能有点晚,但是我刚刚找到这个线程,我之前已经为它创建了我自己的代码……

    list = [1,2,3,4,5]
    deleteList = []
    processNo = 0
    for item in list:
        if condition:
            print item
            deleteList.insert(0, processNo)
        processNo += 1

    if len(deleteList) > 0:
        for item in deleteList:
            del list[item]

It may be a long way of doing it but seems to work well. I create a second list that only holds numbers that relate to the list item to delete. Note the "insert" inserts the list item number at position 0 and pushes the remainder along so when deleting the items, the list is deleted from the highest number back to the lowest number so the list stays in sequence.

这可能需要很长一段路,但似乎很有效。我创建第二个列表,它只保存与要删除的列表项相关的数字。注意,“插入”在位置0处插入列表项号,并将其余的项向前推进,因此在删除项时,列表将从最高的数字删除回最低的数字,以便列表保持顺序。

#7


-5  

Remove function removes the first element in the list (0th index element). In the first iteration of your for loop you start with index number 0, print it. As you move to index number 1 you no longer have 'a' at index location 0 but you have 'b' instead. So what you get will be 'c'. So this code piece will print list elements with even index numbers only.

删除函数删除列表中的第一个元素(第0个索引元素)。在for循环的第一次迭代中,从索引号0开始,打印它。当你移动到索引1时,索引位置0处不再有a,而是有b。你得到的是c。这段代码将只打印索引号为偶数的列表元素。

#1


70  

You are not permitted to remove elements from the list while iterating over it using a for loop.

在使用for循环对列表进行迭代时,不允许从列表中删除元素。

The best way to rewrite the code depends on what it is you're trying to do.

重写代码的最佳方式取决于您要做什么。

For example, your code is equivalent to:

例如,您的代码相当于:

for item in a:
  print item
a[:] = []

Alternatively, you could use a while loop:

您也可以使用while循环:

while a:
  print a.pop(0)

I'm trying to remove items if they match a condition. Then I go to next item.

如果它们符合条件,我就试着删除它们。然后我进入下一项。

You could copy every element that does match the condition into a second list:

你可以将所有符合条件的元素复制到第二个列表中:

result = []
for item in a:
  if condition:
    result.append(item)
a = result

Alternatively, you could use filter or a list comprehension and assign the result back to a:

您也可以使用过滤器或列表理解,并将结果返回给a:

a = filter(lambda item:... , a)

or

a = [item for item in a if ...]

where ... stands for the condition that you need to check.

在那里……表示您需要检查的条件。

#2


32  

Iterate through a copy of the list:

迭代列表的副本:

>>> a = ["a", "b", "c", "d", "e"]
>>> for item in a[:]:
    print item
    if item == "b":
        a.remove(item)

a
b
c
d
e
>>> print a
['a', 'c', 'd', 'e']

#3


9  

As other answers have said, the best way to do this involves making a new list - either iterate over a copy, or construct a list with only the elements you want and assign it back to the same variable. The difference between these depends on your use case, since they affect other variables for the original list differently (or, rather, the first affects them, the second doesn't).

正如其他答案所言,实现此目的的最佳方法是创建一个新列表——要么在副本上迭代,要么构造一个只包含您想要的元素的列表,并将其分配回相同的变量。它们之间的差异取决于您的用例,因为它们对原始列表的其他变量有不同的影响(或者,更确切地说,第一个影响它们,第二个不影响)。

If a copy isn't an option for some reason, you do have one other option that relies on an understanding of why modifying a list you're iterating breaks. List iteration works by keeping track of an index, incrementing it each time around the loop until it falls off the end of the list. So, if you remove at (or before) the current index, everything from that point until the end shifts one spot to the left. But the iterator doesn't know about this, and effectively skips the next element since it is now at the current index rather than the next one. However, removing things that are after the current index doesn't affect things.

如果出于某种原因,副本不是选项,那么您还有一个选项,它依赖于您对为什么要修改列表进行迭代的理解。列表迭代的工作方式是跟踪一个索引,每次循环递增一个索引,直到它从列表的末尾消失。所以,如果你在当前索引处(或之前)移除,从该点到末端都向左移动一个点。但是迭代器不知道这一点,并且有效地跳过了下一个元素,因为它现在是在当前索引中,而不是下一个元素。但是,删除当前索引之后的内容不会影响到其他内容。

This implies that if you iterate the list back to front, if you remove an item at the current index, everything to it's right shifts left - but that doesn't matter, since you've already dealt with all the elements to the right of the current position, and you're moving left - the next element to the left is unaffected by the change, and so the iterator gives you the element you expect.

这意味着如果你回到前面迭代列表,如果删除一个项目目前的指数,它的一切左移右——但这并不重要,因为你已经处理的所有元素的当前位置,和你走左,下一个元素左边是变化的影响,因此,迭代器给你你希望的元素。

TL;DR:

TL;博士:

>>> a = list(range(5))
>>> for b in reversed(a):
    if b == 3:
        a.remove(b)
>>> a
[0, 1, 2, 4]

However, making a copy is usually better in terms of making your code easy to read. I only mention this possibility for sake of completeness.

然而,复制代码通常更容易阅读。为了完整起见,我只提到这种可能性。

#4


2  

How about creating a new list and adding elements you want to that new list. You cannot remove elements while iterating through a list

如何创建一个新的列表并添加您想要的元素到新的列表中呢?在遍历列表时不能删除元素。

#5


1  

import copy

a = ["a", "b", "c", "d", "e"]

b = copy.copy(a)

for item in a:
    print item
    b.remove(item)
a = copy.copy(b)

Works: to avoid changing the list you are iterating on, you make a copy of a, iterate over it and remove the items from b. Then you copy b (the altered copy) back to a.

工作:为了避免更改正在迭代的列表,您将复制a,对其进行迭代,并从b中删除项。然后将b(已修改的副本)复制回a。

#6


0  

Probably a bit late to answer this but I just found this thread and I had created my own code for it previously...

回答这个问题可能有点晚,但是我刚刚找到这个线程,我之前已经为它创建了我自己的代码……

    list = [1,2,3,4,5]
    deleteList = []
    processNo = 0
    for item in list:
        if condition:
            print item
            deleteList.insert(0, processNo)
        processNo += 1

    if len(deleteList) > 0:
        for item in deleteList:
            del list[item]

It may be a long way of doing it but seems to work well. I create a second list that only holds numbers that relate to the list item to delete. Note the "insert" inserts the list item number at position 0 and pushes the remainder along so when deleting the items, the list is deleted from the highest number back to the lowest number so the list stays in sequence.

这可能需要很长一段路,但似乎很有效。我创建第二个列表,它只保存与要删除的列表项相关的数字。注意,“插入”在位置0处插入列表项号,并将其余的项向前推进,因此在删除项时,列表将从最高的数字删除回最低的数字,以便列表保持顺序。

#7


-5  

Remove function removes the first element in the list (0th index element). In the first iteration of your for loop you start with index number 0, print it. As you move to index number 1 you no longer have 'a' at index location 0 but you have 'b' instead. So what you get will be 'c'. So this code piece will print list elements with even index numbers only.

删除函数删除列表中的第一个元素(第0个索引元素)。在for循环的第一次迭代中,从索引号0开始,打印它。当你移动到索引1时,索引位置0处不再有a,而是有b。你得到的是c。这段代码将只打印索引号为偶数的列表元素。