如何展望Python生成器中的一个元素(peek)?

2024-06-01 22:03:06 发布

您现在位置:Python中文网/ 问答频道 /正文

我不知道如何展望Python生成器中的一个元素。我一看就不见了。

我的意思是:

gen = iter([1,2,3])
next_value = gen.next()  # okay, I looked forward and see that next_value = 1
# but now:
list(gen)  # is [2, 3]  -- the first value is gone!

下面是一个更真实的例子:

gen = element_generator()
if gen.next_value() == 'STOP':
  quit_application()
else:
  process(gen.next())

有谁能帮我写一个发电机,你可以向前看一个元素吗?


Tags: and元素thatisvaluenowlistbut
2条回答

好吧——晚了两年——但我遇到了这个问题,没有找到任何令我满意的答案。提出了这个元生成器:

class Peekorator(object):

    def __init__(self, generator):
        self.empty = False
        self.peek = None
        self.generator = generator
        try:
            self.peek = self.generator.next()
        except StopIteration:
            self.empty = True

    def __iter__(self):
        return self

    def next(self):
        """
        Return the self.peek element, or raise StopIteration
        if empty
        """
        if self.empty:
            raise StopIteration()
        to_return = self.peek
        try:
            self.peek = self.generator.next()
        except StopIteration:
            self.peek = None
            self.empty = True
        return to_return

def simple_iterator():
    for x in range(10):
        yield x*3

pkr = Peekorator(simple_iterator())
for i in pkr:
    print i, pkr.peek, pkr.empty

结果:

0 3 False
3 6 False
6 9 False
9 12 False    
...
24 27 False
27 None False

也就是说,在迭代过程中,您随时可以访问列表中的下一项。

为了完整起见,^{} package(可能应该是任何Python程序员工具箱的一部分)包含实现此行为的peekable包装器。正如the documentation中的代码示例所示:

>>> p = peekable(xrange(2))
>>> p.peek()
0
>>> p.next()
0
>>> p.peek()
1
>>> p.next()
1

尽管文档显示了Python2语法,但该包与Python2和3都兼容。

Python生成器API是一种方法:您不能回推已读的元素。但是您可以使用itertools module创建一个新的迭代器,并预先设置元素:

import itertools

gen = iter([1,2,3])
peek = gen.next()
print list(itertools.chain([peek], gen))

相关问题 更多 >