Python 如何在迭代时从列表中删除项?

Python 如何在迭代时从列表中删除项?,python,iteration,Python,Iteration,我在Python中迭代元组列表,如果它们满足某些条件,我将尝试删除它们 for tup in somelist: if determine(tup): code_to_remove_tup 我应该用什么来代替code\u来删除安装程序?我不知道如何以这种方式删除该项。您需要先复制一份列表并对其进行迭代,否则迭代将失败,结果可能会出乎意料 例如(取决于列表的类型): 例如: >>> somelist = range(10) >>> f

我在Python中迭代元组列表,如果它们满足某些条件,我将尝试删除它们

for tup in somelist:
    if determine(tup):
         code_to_remove_tup

我应该用什么来代替
code\u来删除安装程序
?我不知道如何以这种方式删除该项。

您需要先复制一份列表并对其进行迭代,否则迭代将失败,结果可能会出乎意料

例如(取决于列表的类型):

例如:

>>> somelist = range(10)
>>> for x in somelist:
...     somelist.remove(x)
>>> somelist
[1, 3, 5, 7, 9]

>>> somelist = range(10)
>>> for x in somelist[:]:
...     somelist.remove(x)
>>> somelist
[]

您需要获取列表的副本并首先对其进行迭代,否则迭代将失败,结果可能是意外的

例如(取决于列表的类型):

例如:

>>> somelist = range(10)
>>> for x in somelist:
...     somelist.remove(x)
>>> somelist
[1, 3, 5, 7, 9]

>>> somelist = range(10)
>>> for x in somelist[:]:
...     somelist.remove(x)
>>> somelist
[]

对于这样一个例子,您最好的方法是

如果您正在执行比调用
determinate
函数更复杂的操作,我更喜欢构建一个新列表,并在执行时简单地将其添加到列表中。比如说

newlist = []
for tup in somelist:
    # lots of code here, possibly setting things up for calling determine
    if determine(tup):
        newlist.append(tup)
somelist = newlist
使用
remove
复制列表可能会使您的代码看起来更干净,如下面的一个答案所述。对于非常大的列表,您绝对不应该这样做,因为这涉及到首先复制整个列表,并对要删除的每个元素执行
O(n)
remove
操作,使其成为
O(n^2)
算法

for tup in somelist[:]:
    # lots of code here, possibly setting things up for calling determine
    if determine(tup):
        newlist.append(tup)

对于这样一个例子,您最好的方法是

如果您正在执行比调用
determinate
函数更复杂的操作,我更喜欢构建一个新列表,并在执行时简单地将其添加到列表中。比如说

newlist = []
for tup in somelist:
    # lots of code here, possibly setting things up for calling determine
    if determine(tup):
        newlist.append(tup)
somelist = newlist
使用
remove
复制列表可能会使您的代码看起来更干净,如下面的一个答案所述。对于非常大的列表,您绝对不应该这样做,因为这涉及到首先复制整个列表,并对要删除的每个元素执行
O(n)
remove
操作,使其成为
O(n^2)
算法

for tup in somelist[:]:
    # lots of code here, possibly setting things up for calling determine
    if determine(tup):
        newlist.append(tup)

您可以使用列表理解创建一个新列表,其中只包含您不想删除的元素:

somelist = [x for x in somelist if not determine(x)]
或者,通过分配给切片
somelist[:]
,可以改变现有列表,使其仅包含所需的项目:

somelist[:] = [x for x in somelist if not determine(x)]
如果对
somelist
的其他引用需要反映这些更改,那么这种方法可能很有用

您还可以使用
itertools
,而不是理解。在Python 2中:

from itertools import ifilterfalse
somelist[:] = ifilterfalse(determine, somelist)
或者在Python 3中:

from itertools import filterfalse
somelist[:] = filterfalse(determine, somelist)

您可以使用列表理解创建一个新列表,其中只包含您不想删除的元素:

somelist = [x for x in somelist if not determine(x)]
或者,通过分配给切片
somelist[:]
,可以改变现有列表,使其仅包含所需的项目:

somelist[:] = [x for x in somelist if not determine(x)]
如果对
somelist
的其他引用需要反映这些更改,那么这种方法可能很有用

您还可以使用
itertools
,而不是理解。在Python 2中:

from itertools import ifilterfalse
somelist[:] = ifilterfalse(determine, somelist)
或者在Python 3中:

from itertools import filterfalse
somelist[:] = filterfalse(determine, somelist)
你需要向后走,否则就有点像锯掉你坐的树枝:-)

Python 2用户:将
range
替换为
xrange
,以避免创建硬编码列表

你需要向后走,否则就有点像锯掉你坐的树枝:-)


Python 2用户:将
range
替换为
xrange
,以避免为喜欢函数式编程的用户创建硬编码列表:

somelist[:] = filter(lambda tup: not determine(tup), somelist)


对于那些喜欢函数式编程的人:

somelist[:] = filter(lambda tup: not determine(tup), somelist)


建议列表理解的答案几乎是正确的——除了它们构建了一个全新的列表,然后给它起了与旧列表相同的名字,它们没有修改旧列表。这与选择性删除不同,比如更快,但是如果通过多个引用访问列表,那么只需重新放置其中一个引用,而不更改列表对象本身,就会导致微妙的灾难性错误

幸运的是,获得列表理解的速度和就地更改所需的语义非常容易——只需代码:

somelist[:] = [tup for tup in somelist if determine(tup)]

请注意与其他答案的细微差别:这一答案并不是指定给一个单名,而是指定给恰好是整个列表的列表片,从而替换同一个Python列表对象中的列表内容,而不仅仅是重新放置一个引用(从上一个列表对象到新列表对象)与其他答案一样。

建议列表理解的答案几乎是正确的——只是它们构建了一个全新的列表,然后给它起了与旧列表相同的名字,因为它们没有修改旧列表。这与选择性删除不同,比如更快,但是如果通过多个引用访问列表,那么只需重新放置其中一个引用,而不更改列表对象本身,就会导致微妙的灾难性错误

幸运的是,获得列表理解的速度和就地更改所需的语义非常容易——只需代码:

somelist[:] = [tup for tup in somelist if determine(tup)]

请注意与其他答案的细微差别:这一答案并不是指定给一个单名,而是指定给恰好是整个列表的列表片,从而替换同一个Python列表对象中的列表内容,而不仅仅是重新放置一个引用(从上一个列表对象到新列表对象)与其他答案一样。

您可能希望使用内置的
filter()


有关更多详细信息,请使用内置的
filter()


要了解更多详细信息,如果您想在迭代过程中执行任何其他操作,最好同时获取索引(这保证您能够引用它,例如,如果您有一个dict列表)和实际的列表项内容

inlist = [{'field1':10, 'field2':20}, {'field1':30, 'field2':15}]    
for idx, i in enumerate(inlist):
    do some stuff with i['field1']
    if somecondition:
        xlist.append(idx)
for i in reversed(xlist): del inlist[i]
枚举
允许您访问
for item in originalList:
   if (item != badValue):
        newList.append(item)
originalList[:] = newList
from fluidIter import FluidIterable
fSomeList = FluidIterable(someList)  
for tup in fSomeList:
    if determine(tup):
        # remove 'tup' without "breaking" the iteration
        fSomeList.remove(tup)
        # tup has also been removed from 'someList'
        # as well as 'fSomeList'
from fluidIter import FluidIterable
l = [0,1,2,3,4,5,6,7,8]  
fluidL = FluidIterable(l)                       
for i in fluidL:
    print('initial state of list on this iteration: ' + str(fluidL)) 
    print('current iteration value: ' + str(i))
    print('popped value: ' + str(fluidL.pop(2)))
    print(' ')

print('Final List Value: ' + str(l))
initial state of list on this iteration: [0, 1, 2, 3, 4, 5, 6, 7, 8]
current iteration value: 0
popped value: 2

initial state of list on this iteration: [0, 1, 3, 4, 5, 6, 7, 8]
current iteration value: 1
popped value: 3

initial state of list on this iteration: [0, 1, 4, 5, 6, 7, 8]
current iteration value: 4
popped value: 4

initial state of list on this iteration: [0, 1, 5, 6, 7, 8]
current iteration value: 5
popped value: 5

initial state of list on this iteration: [0, 1, 6, 7, 8]
current iteration value: 6
popped value: 6

initial state of list on this iteration: [0, 1, 7, 8]
current iteration value: 7
popped value: 7

initial state of list on this iteration: [0, 1, 8]
current iteration value: 8
popped value: 8

Final List Value: [0, 1]
fluidL[2] = 'a'   # is OK
fluidL = [0, 1, 'a', 3, 4, 5, 6, 7, 8]  # is not OK
fluidArr = FluidIterable([0,1,2,3])
# get iterator first so can query the current index
fluidArrIter = fluidArr.__iter__()
for i, v in enumerate(fluidArrIter):
    print('enum: ', i)
    print('current val: ', v)
    print('current ind: ', fluidArrIter.currentIndex)
    print(fluidArr)
    fluidArr.insert(0,'a')
    print(' ')

print('Final List Value: ' + str(fluidArr))
enum:  0
current val:  0
current ind:  0
[0, 1, 2, 3]

enum:  1
current val:  1
current ind:  2
['a', 0, 1, 2, 3]

enum:  2
current val:  2
current ind:  4
['a', 'a', 0, 1, 2, 3]

enum:  3
current val:  3
current ind:  6
['a', 'a', 'a', 0, 1, 2, 3]

Final List Value: ['a', 'a', 'a', 'a', 0, 1, 2, 3]
originalList = fluidArr.fixedIterable
newList = [i for i in oldList if testFunc(i)]
randInts = [70, 20, 61, 80, 54, 18, 7, 18, 55, 9]
fRandInts = FluidIterable(randInts)
fRandIntsIter = fRandInts.__iter__()
# for each value in the list (outer loop)
# test against every other value in the list (inner loop)
for i in fRandIntsIter:
    print(' ')
    print('outer val: ', i)
    innerIntsIter = fRandInts.__iter__()
    for j in innerIntsIter:
        innerIndex = innerIntsIter.currentIndex
        # skip the element that the outloop is currently on
        # because we don't want to test a value against itself
        if not innerIndex == fRandIntsIter.currentIndex:
            # if the test element, j, is a multiple 
            # of the reference element, i, then remove 'j'
            if j%i == 0:
                print('remove val: ', j)
                # remove element in place, without breaking the
                # iteration of either loop
                del fRandInts[innerIndex]
            # end if multiple, then remove
        # end if not the same value as outer loop
    # end inner loop
# end outerloop

print('')
print('final list: ', randInts)
outer val:  70

outer val:  20
remove val:  80

outer val:  61

outer val:  54

outer val:  18
remove val:  54
remove val:  18

outer val:  7
remove val:  70

outer val:  55

outer val:  9
remove val:  18

final list:  [20, 61, 7, 55, 9]
alist = ['good', 'bad', 'good', 'bad', 'good']
i = 0
for x in alist[:]:
    if x == 'bad':
        alist.pop(i)
        i -= 1
    # do something cool with x or just print x
    print(x)
    i += 1
>>> L1 = [(1,2), (5,6), (-1,-2), (1,-2)]
>>> for (a,b) in L1:
...   if a < 0 or b < 0:
...     L1.remove(a,b)
... 
Traceback (most recent call last):
  File "<stdin>", line 3, in <module>
TypeError: remove() takes exactly one argument (2 given)
>>> L1[1]
(5, 6)
>>> type(L1[1])
<type 'tuple'>
# The remove line now includes an extra "()" to make a tuple out of "a,b"
L1.remove((a,b))
L1 is now: [(1, 2), (5, 6), (1, -2)]
L1 = [(1,2),(5,6),(-1,-2),(1,-2),(3,4),(5,7),(-4,4),(2,1),(-3,-3),(5,-1),(0,6)]
### Outputs:
L1 is now: [(1, 2), (5, 6), (1, -2), (3, 4), (5, 7), (2, 1), (5, -1), (0, 6)]
L2 = L1
for (a,b) in L1:
    if a < 0 or b < 0 :
        L2.remove((a,b))
# Now, remove the original copy of L1 and replace with L2
print L2 is L1
del L1
L1 = L2; del L2
print ("L1 is now: ", L1)
'L1 is now: ', [(1, 2), (5, 6), (1, -2), (3, 4), (5, 7), (2, 1), (5, -1), (0, 6)]
>>> L2=L1
>>> L1 is L2
True
import copy
L1 = [(1,2), (5,6),(-1,-2), (1,-2),(3,4),(5,7),(-4,4),(2,1),(-3,-3),(5,-1),(0,6)]
L2 = copy.copy(L1)
for (a,b) in L1:
    if a < 0 or b < 0 :
        L2.remove((a,b))
# Now, remove the original copy of L1 and replace with L2
del L1
L1 = L2; del L2
>>> L1 is now: [(1, 2), (5, 6), (3, 4), (5, 7), (2, 1), (0, 6)]
L1 = [(1,2), (5,6),(-1,-2), (1,-2),(3,4),(5,7),(-4,4),(2,1),(-3,-3),(5,-1),(0,6)]
for (a,b) in reversed(L1):
    if a < 0 or b < 0 :
        L1.remove((a,b))
print ("L1 is now: ", L1)
>>> L1 is now: [(1, 2), (5, 6), (3, 4), (5, 7), (2, 1), (0, 6)]
array = [lots of stuff]
arraySize = len(array)
i = 0
while i < arraySize:
    if someTest(array[i]):
        del array[i]
        arraySize -= 1
    else:
        i += 1
for i, item in enumerate(lst):
    if item % 4 == 0:
        foo(item)
        del lst[i]
        break
import numpy as np

orig_list = np.array([1, 2, 3, 4, 5, 100, 8, 13])

remove_me = [100, 1]

cleaned = np.delete(orig_list, remove_me)
print(cleaned)
""" Sieve of Eratosthenes """

def generate_primes(n):
    """ Generates all primes less than n. """
    primes = list(range(2,n))
    idx = 0
    while idx < len(primes):
        p = primes[idx]
        for multiple in range(p+p, n, p):
            try:
                primes.remove(multiple)
            except ValueError:
                pass #EAFP
        idx += 1
        yield p
i = 0
while i < len(somelist):
    if determine(somelist[i]):
         del somelist[i]
    else:
        i += 1
list(filter(lambda x:x%2==1, (1, 2, 4, 5, 6, 9, 10, 15)))  
# result: [1, 5, 9, 15]
for tup in somelist:
    if ( sum(tup)==15 ): 
        del somelist[somelist.index(tup)]

print somelist
>>> [(1, 2, 3), (3, 6, 6), (7, 8, 9), (10, 11, 12)]
newlist1 = [somelist[tup] for tup in range(len(somelist)) if(sum(somelist[tup])!=15)]

print newlist1
>>>[(1, 2, 3), (7, 8, 9), (10, 11, 12)]
indices = [i for i in range(len(somelist)) if(sum(somelist[i])==15)]
newlist2 = [tup for j, tup in enumerate(somelist) if j not in indices]

print newlist2
>>>[(1, 2, 3), (7, 8, 9), (10, 11, 12)]
for i in li:
    i = None

for elem in li:
    if elem is None:
        continue
[5, 7, 13, 29, 65, 91]
lis = [5, 7, 13, 29, 35, 65, 91]
       0  1   2   3   4   5   6
lis.remove(y)
lis = [5, 7, 13, 29, 65, 91]
       0  1   2   3   4   5
ite = lis #dont do it will reference instead copy
[5, 7, 13, 29]
i = 0
length = len(list1)

while i < length:
    if condition:
        list1.remove(list1[i])
        i -= 1
        length -= 1

    i += 1