首页 > 解决方案 > 在迭代列表时从列表中删除项目

问题描述

Python 脚本中有两个单独的进程在运行。两者都与全局变量交互POST_QUEUE = []

以下是 的通用版本P2

def Process_2():
    for post in POST_QUEUE:
        if perform_operation(post):
            Print("Success!")
        else:
            Print("Failure.")
        POST_QUEUE.remove(post)

可以理解的是,我遇到了一个问题,当从 for 循环正在迭代的列表中删除项目时,它会破坏索引并比预期更早终止循环(即,在它对每个帖子执行必要的操作之前和将其从POST_QUEUE) 中删除。

有没有更好的方法来做到这一点而不是在从原始对象中删除项目时创建一个副本POST_QUEUE并对其进行P2迭代?例如:POST_QUEUE

def Process_2():
    POST_QUEUE_COPY = POST_QUEUE[:]
    for post in POST_QUEUE_COPY:
        if perform_operation(post):
            Print("Success!")
        else:
            Print("Failure.")
        POST_QUEUE.remove(post)

标签: pythonfor-loop

解决方案


由于您实际上并不需要元素的索引,因此我建议您将这样的事情作为一个简单的解决方案:

def Process_2():
    while len(POST_QUEUE):
        if perform_operation(post[0]):
            Print("Success!")
        else:
            Print("Failure.")
        POST_QUEUE.remove(post[0])

但是,此解决方案的每次使用循环的运行时间为 O(n^2),因为 python 需要在每次迭代时移动列表中的每个元素。

因此,IMO 更好的实施方式是:

def Process_2():
    reversed_post_queue = POST_QUEUE[::-1]
    while len(reversed_post_queue):
        if perform_operation(post[-1]):
            Print("Success!")
        else:
            Print("Failure.")
        POST_QUEUE.remove(post[-1])

这样你就可以保持顺序(我认为这在整个答案中对你很重要),同时只移动列表的元素一次并导致运行时间为 O(n)

最后,IMO 的最佳实现是创建或导入队列模块,以便您可以轻松地将列表用作 FIFO。


推荐阅读