Python:迭代列表时删除列表元素

时间:2011-05-16 20:12:40

标签: python list

我正在迭代Python中的元素列表,对其执行某些操作,然后在满足特定条件时将其删除。

for element in somelist:
    do_action(element)
    if check(element):
        remove_element_from_list

我应该使用什么代替remove_element? 我已经看到了类似的问题,但注意到要为所有元素执行的do_action部分的存在,从而消除了使用过滤器的解决方案。

9 个答案:

答案 0 :(得分:124)

您可以随时遍历列表的副本,让您可以自由修改原始文件:

for item in list(somelist):
  ...
  somelist.remove(item)

答案 1 :(得分:109)

符合以下条件:原位修改原始列表,没有列表副本,只有一个通道,工作,传统解决方案是向后迭代

for i in xrange(len(somelist) - 1, -1, -1):
    element = somelist[i]
    do_action(element)
    if check(element):
        del somelist[i]

奖励:每次迭代都不会len(somelist)。适用于任何版本的Python(至少可以追溯到1.5.2)... s / xrange / range / for 3.X。

更新:如果你想迭代前进,那么这是可能的,只是更棘手和更丑陋:

i = 0
n = len(somelist)
while i < n:
    element = somelist[i]
    do_action(element)
    if check(element):
        del somelist[i]
        n = n - 1
    else:
        i = i + 1

答案 2 :(得分:10)

列出补偿:

results = [x for x in (do_action(element) for element in somelist) if check(element)]

答案 3 :(得分:7)

for element in somelist:
    do_action(element)
somelist[:] = (x for x in somelist if not check(x))

如果你真的需要一次性完成而不复制列表

i=0
while i < len(somelist):
    element = somelist[i] 
    do_action(element)
    if check(element):
        del somelist[i]
    else:
        i+=1

答案 4 :(得分:7)

你仍然可以使用过滤器,移动到外部函数元素修改(只迭代一次)

def do_the_magic(x):
    do_action(x)
    return check(x)

# you can get a different filtered list
filter(do_the_magic,yourList)

# or have it modified in place (as suggested by Steven Rumbalski, see comment)
yourList[:] = itertools.ifilter(do_the_magic, yourList)

答案 5 :(得分:2)

您可以创建一个返回未删除内容的生成器:

def newlist(somelist):
    for element in somelist:
        do_action(element)
        if not check(element):
            yield element

答案 6 :(得分:2)

另一种方法是:

while i<len(your_list):
    if #condition :
        del your_list[i]
    else:
        i+=1

因此,您在检查

时并排删除元素

答案 7 :(得分:0)

为什么不把它重写为

for element in somelist: 
   do_action(element)  

if check(element): 
    remove_element_from_list

有关如何从列表中删除的信息,请参阅此问题,尽管看起来您已经看过了 Remove items from a list while iterating

另一个选择是如果你真的想保持这个

的话
newlist = [] 
for element in somelist: 
   do_action(element)  

   if not check(element): 
      newlst.append(element)

答案 8 :(得分:0)

不完全就位,但有些想法可以做到:

a = ['a', 'b']

def inplace(a):
    c = []
    while len(a) > 0:
        e = a.pop(0)
        if e == 'b':
            c.append(e)
    a.extend(c)

您可以扩展该功能,以便在条件下调用您的过滤器。