【问题标题】:Python while loop popleft() - ERROR: Empty dequePython while循环popleft() - 错误:空双端队列
【发布时间】:2013-02-15 16:28:12
【问题描述】:

我正在为这个循环寻找更优雅的解决方案。我的双端队列是动态创建的,长度可能不同。在下面的示例中,列表只有两个项目长,最多可以有 3 个项目长。在我的应用程序中,列表最多可以包含 30 个项目。因此,我想避免编写大量 if 语句,并在双端队列为空时停止执行代码。

from collections import deque

my_list = [ 1,2 ]
my_deque = deque ( my_list )

while my_deque:
    alpha = my_deque.popleft()
    beta = my_deque.popleft()
    gamma = my_deque.popleft()

上面的代码执行所有三个命令,并在 gamma 命令上返回“IndexError: pop from an empty deque”。我了解为什么会发生此错误,但想知道是否缺少一个技巧来评估列表/双端队列在 while 循环中间是否为空(或另一种循环遍历长列表的创造性方法) .

感谢您的帮助。

【问题讨论】:

    标签: python list indexing while-loop deque


    【解决方案1】:

    您可以捕获 IndexError:

    try:
        while mydeque:
            alpha = mydeque.popleft()
            beta = mydeque.popleft()
            gamma = mydeque.popleft()
    except IndexError:
        # handle empty mydeque
    

    你想做什么?为什么要检查 mydeque 是否为空?

    【讨论】:

    • 这行得通。 gamma 实际上是字典中的一个键。我认为 try / except 使 try 中的所有代码或全部代码都必须执行。没有意识到在异常之前执行的任何操作仍然会完成。谢谢!
    • @ccdpowell:但要小心,如果代码的其他部分也可能引发 IndexError,那么 try-except 也可能会捕获到它。将 try except 放在 while 循环中可能会更好,只围绕您拥有 mydeque.popleft() 的部分,但这实际上取决于您要执行的操作。
    【解决方案2】:

    您可以像在while 循环中一样使用完全相同的方式签入:

    while my_deque:
        alpha = my_deque.popleft()
        beta = my_deque.popleft() if my_deque else None
        gamma = my_deque.popleft() if my_deque else None
    

    但是,如果 alphabetagamma 构成一个工作单元,那么将它们组合成一个元组并将其加入队列可能会更好。

    【讨论】:

    • 当我用 if 语句代替 while 语句执行我的代码块时,它仍然不起作用。同样的错误。从回溯:“回溯(最近一次调用最后一次):文件“test.py”,第 9 行,在 gamma = my_deque.popleft() IndexError: pop from an empty deque"
    • @ccdpowell:我不是这个意思。您需要在每个popleft() 之前检查队列是否为空。我已经更新了代码,希望它更清晰。
    【解决方案3】:

    如果您知道要从队列中弹出多少项目,则可以将循环设置为至少有那么多准备好:

    while len(my_deque) >= 3:
        alpha = my_deque.popleft()
        beta = my_deque.popleft()
        gamma = my_deque.popleft()
    
        # do stuff with alpha/beta/gamma here
    

    如果您不知道可以请求多少项,您可以采取“请求宽恕比请求许可更容易”的方法并无条件循环:

    while True:
        try:
            alpha = my_deque.popleft()
            if alpha > 0:
                beta = my_deque.popleft()
                gamma = my_deque.popleft()
            else:
                beta = 0
                gamma = 0
        except IndexError:
            break
    
        # do stuff with alpha/beta/gamma here
    

    如果 pop 发生在循环代码的广泛分离的部分,您可以为每个部分使用单独的 try/except 块,而不是将整个内容包装在一个单独的块中。

    【讨论】:

      猜你喜欢
      • 2014-04-18
      • 1970-01-01
      • 2014-08-11
      • 1970-01-01
      • 1970-01-01
      • 2012-10-10
      • 1970-01-01
      • 2013-05-21
      • 2011-02-14
      相关资源
      最近更新 更多