【问题标题】:How to peek front of deque without popping?如何在不弹出的情况下查看双端队列的前面?
【发布时间】:2018-07-16 08:28:08
【问题描述】:

我想在决定是否弹出之前检查队列前面的条件。如何在 python 中使用 collections.deque 实现这一点?

list(my_deque)[0]

看起来丑陋且性能不佳。

【问题讨论】:

  • 没有必要转换为list,因为deque 支持直接索引。此外,队列的“前面”是deque 的列表表示中的最后一个 元素(即索引-1),而不是第一个。

标签: python collections deque


【解决方案1】:

假设你的双端队列是从集合 python 实现的

from collections import deque
deque = deque() //syntax

就使用索引进行访问而言,Deque 也可以解释为列表。 您可以使用deque[0] 查看前面的元素,使用deque[-1] 查看最后一个元素 这可以在不从左侧或右侧弹出元素的情况下工作,而且看起来也很有效。

【讨论】:

    【解决方案2】:

    这是一个简单的实现,它允许我在弹出之前检查队列的前面(使用while 和q[0]):

    将您自己的条件应用于q[0],在q.popleft() 之前,如下:

    testLst = [100,200,-100,400,340]
    q=deque(testLst)
    
    while q:
        print(q)
        print('{}{}'.format("length of queue: ", len(q)))
        print('{}{}'.format("head: ", q[0]))
        print()
    
        q.popleft()
    

    输出:

    deque([100, 200, -100, 400, 340])
    length of queue: 5
    head: 100
    
    deque([200, -100, 400, 340])
    length of queue: 4
    head: 200
    
    deque([-100, 400, 340])
    length of queue: 3
    head: -100
    
    deque([400, 340])
    length of queue: 2
    head: 400
    
    deque([340])
    length of queue: 1
    head: 340
    

    【讨论】:

      【解决方案3】:

      TL;DR:假设您的deque 被称为d,只需检查d[-1],因为双端队列中的“最右边”元素是前面(您可能想在之前测试双端队列的长度以确保它不为空)。采纳@ason​​gtoruin 的建议,使用if d: 测试deque 是否为空(相当于if len(d) == 0:,但更pythonic)

      为什么不转换成列表?

      因为deques 是可索引的并且您正在测试前端。虽然deque 具有类似于列表的接口,但其实现已针对前后操作进行了优化。引用documentation:

      双端队列支持线程安全、内存高效的追加和弹出 双端队列的任一侧具有大致相同的 O(1) 性能 任一方向。

      虽然列表对象支持类似的操作,但它们已针对 快速固定长度操作并产生 O(n) 内存移动成本 pop(0) 和 insert(0, v) 操作同时改变大小和 底层数据表示的位置。

      如果您有大量操作访问队列的“中间”,则可能需要转换为列表。再次引用文档:

      索引访问在两端都是 O(1),但在中间慢到 O(n)。 对于快速随机访问,请改用列表。

      转换为list 是 O(n),但每次后续访问都是 O(1)。

      【讨论】:

      • 您应该能够直接检查双端队列是否为空,而无需检查其长度(即if d: 而不是if len(d) > 0:)
      • @ason​​gtoruin 我认为这是一个隐式长度测试,因为这两个语句是等价的,但当然if d: 是更 Pythonic 的编写方式。
      • 我找了一份副本,但找不到。你有我的紫外线!您可以补充说,转换为 list 不仅丑陋而且性能不佳
      • 我意识到我在迂腐 - 你的回答是正确的,但我可以看到有人可能认为len 是必需的
      • 等一下,根据你使用双端队列的方式,双端队列的“前端”可能在开头! (即d[0])
      【解决方案4】:

      您可以使用 my_deque[-1] 或 my_deque[len(my_deque)-1] 简单地找到最后一个元素。

      【讨论】:

        猜你喜欢
        • 2017-04-04
        • 2018-09-08
        • 2018-03-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-05-21
        • 2012-03-19
        • 2018-02-17
        相关资源
        最近更新 更多