是否有一些标记最后一个序列的内置?

时间:2015-03-08 23:33:14

标签: python generator

我需要这样的东西:

>>> for i in mark_last([1, 2, 3]):
...  print(i)
... 
(1, False)
(2, False)
(3, True)

我是这样实现的,但是......

def mark_last(li):
    items = iter(items)
    try:
        prev = next(items)
    except StopIteration:
        return
    for item in items:
        yield prev, False
        prev = item
    yield prev, True

这是否有内置功能?或者更简短的方法呢?也许与itertools.groupby()结合的东西? - 不接受具有len()的技巧,因为它们不适用于生成器。

4 个答案:

答案 0 :(得分:2)

您可以使用mark_last来定义iwindow,这会返回滑动 可迭代的窗口。

import itertools as IT

def iwindow(iterable, n=2):
    """
    Returns a sliding window (of width n) over data from the sequence.
    s -> (s0,s1,...s[n-1]), (s1,s2,...,sn), ...
    """
    iterables = IT.tee(iterable, n)
    iterables = (IT.islice(it, pos, None) for pos, it in enumerate(iterables))
    for result in IT.izip(*iterables):
        yield result

def mark_last(iterable):
    for i, j in iwindow(iterable):
        yield i, False
    yield j, True

for i in mark_last([1, 2, 3]):
    print(i)

产量

(1, False)
(2, False)
(3, True)

请注意,您可以直接使用iwindow来解决问题,而不需要mark_last

答案 1 :(得分:2)

  

是否有一些内置标记序列的最后一个?

不,没有。

你的功能很好,除了两点:

  1. 它如何处理空序列?
  2. 而不是raise StopIteration你应该break;最终raise StopIteration会产生RunTimeErrorPEP 479)。

答案 2 :(得分:2)

你提供的更简洁的版本是

def mark_last(items):
    items = iter(items)

    prev = next(items)
    for item in items:
        yield prev, False
        prev = item

    yield item, True

请注意,不推荐使用裸next引发StopIteration,因此您可能希望使用明确的try...except

答案 3 :(得分:0)

在Python 3 +中

对于大型列表,这可能有点难以实现...

>>> def mark_last(iterable):
...     *others, last = iterable
...     for element in others:
...             yield (element, False)
...     yield (last, True)
...
>>> for i in mark_last([1, 2, 3]):
...     print(i)
...
(1, False)
(2, False)
(3, True)

From the docs

  

如果目标列表包含一个前缀为星号的目标,   称为“已加星标”的目标:对象必须至少是一个序列   与目标列表中的目标一样多的项目减去一个。的的   序列的第一项从左到右分配给   在加星标的目标之前的目标。序列的最后一项是   在已加星标的目标后分配给目标。一份清单   然后,序列中的剩余项目将分配给已加星标的目标   (列表可以为空)。

这是在*others, last = iterable行上完成的,但反之亦然。