【问题标题】:How to get the item to be discarded in python deque?如何让项目在python deque中被丢弃?
【发布时间】:2014-03-11 07:58:50
【问题描述】:

假设我们有一个deque 和maxlen=3。如果deque 已经有 3 个项目,而当我 append 一个新项目时,我怎样才能得到将要被丢弃的项目?

原因是我想在内存中维护一个只包含最后N个项目的窗口,当窗口已满并且要丢​​弃一个项目时,我需要获取该项目并做一些额外的工作。

这是我目前的解决方案:

from collection import deque

MAX_LEN=10

q = deque(maxlen=MAX_LEN)

while True:
    if len(q) == MAX_LEN:
        discarded = q.popleft()
        process(discarded)
    q.append(some_var)

这是我能得到的最好的吗?我曾考虑过使用list 并对列表进行切片以限制大小/获取丢弃的项目,但if 是不可避免的。使用deque 至少我可以在push 和popleft 操作中获得O(1) 的性能。

有什么想法吗?

【问题讨论】:

  • 为什么不process(q[0]); q.append(some_var)?
  • @Bakuriu 我需要处理要丢弃的那个。所以队列从 0 项开始,当达到 3 项时,我需要开始处理q[0]。我只是想避免循环中的if 比较。
  • 你的代码没有问题,我也不认为你可以做得更好。尽管您可以摆脱discarded 变量。你可以创建一个新的子类来为你做这件事
  • 您希望在这里实现什么?长度测试不可能对性能产生重大影响,那么通过尝试优化它可以获得什么?此外,以一种或另一种方式,您必须检查您是否处于最大长度,所以我认为您能做的最多是process(q.popleft()),而不会将临时变量绑定到discarded。跨度>
  • deque 是正确的数据结构(就效率而言),但它没有提供实现您想要的“内置”方式(这基本上是一个回调与maxlen...结合使用)。避免显式 if 的唯一方法是将其隐藏到一些可能是子类或(恕我直言)deque 的简单包装器的代码中。

标签: python deque


【解决方案1】:

这样的事情可能对你有用。

def pairwise(iterable, n=2 ):
    from itertools import tee, islice, izip
    return izip(*(islice(it,pos,None) for pos,it in enumerate(tee(iterable, n))))


for values in pairwise(infinite_iterable_generating_your_values, n=3):
    process(values[0])
    if breakconditions:
        break 

成对函数示例:

print [i for i in pairwise(range(10), n=3)]

[(0, 1, 2), (1, 2, 3), (2, 3, 4), (3, 4, 5), (4, 5, 6), (5, 6, 7), (6, 7, 8), (7, 8, 9)]

【讨论】:

    【解决方案2】:

    获取即将被丢弃的项目的预期方法是使用索引查找:[0]:

    >>> from collections import deque
    
    >>> d = deque('abc', maxlen=3)
    >>> about_to_be_discarded = d[0]
    >>> about_to_be_discarded
    'a'
    >>> d.append('d')
    >>> d
    deque(['b', 'c', 'd'], maxlen=3)
    

    第二个问题是避免使用if 来确定双端队列是否已满。一种方法是有两个单独的循环,一个最初填充窗口,另一个在加载新值时处理丢弃:

    d = deque(maxlen=n)
    for i in range(n):
        d.append(get_input_value())
    while True:
        discard = d[0]
        d.append(get_input_value())
        process(discard)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-15
      • 1970-01-01
      • 1970-01-01
      • 2011-03-03
      相关资源
      最近更新 更多