需要在python中的迭代器的开头添加一个元素

时间:2009-08-12 05:14:13

标签: python iterator

我有一个程序如下:

a=reader.next()
if *some condition holds*:
    #Do some processing and continue the iteration
else:
    #Append the variable a back to the iterator
    #That is nullify the operation *a=reader.next()*

如何在迭代器的开头添加元素? (或者有更简单的方法吗?)

编辑:好的,让我这样说吧。我需要迭代器中的下一个元素而不删除它。  我该怎么做>?

4 个答案:

答案 0 :(得分:10)

因此,Python迭代器的功能非常有限 - 没有“附加”或类似的东西。您需要将通用迭代器包装在添加该功能的包装器中。 E.g:

class Wrapper(object):
  def __init__(self, it):
    self.it = it
    self.pushedback = []
  def __iter__(self):
    return self
  def next(self):
    if self.pushedback:
      return self.pushedback.pop()
    else:
      return self.it.next()
  def pushback(self, val):
    self.pushedback.append(val)

这是Python 2.5(也应该在2.6中工作) - 建议2.6的轻微变体和3.any强制使用(使用next(self.it)代替self.it.next()并定义__next__而不是next)。

编辑:OP现在说他们需要的是“在没有消费的情况下向前看”。包装仍然是最佳选择,但另一种选择是:

import itertools
   ...
o, peek = itertools.tee(o)
if isneat(peek.next()): ...

这不会提前o(如果您决定要这样做,请记得推进它; - )。

答案 1 :(得分:2)

通过设计(在一般开发概念中)迭代器旨在是只读的,任何改变它们的尝试都会破坏。

或者,您可以向后读取迭代器,并将其添加到hte元素的末尾(实际上是开始:))?

答案 2 :(得分:2)

您正在寻找itertools.chain

import itertools

values = iter([1,2,3])  # the iterator
value = 0  # the value to prepend to the iterator

together = itertools.chain([value], values)  # there it is

list(together)
# -> [0, 1, 2, 3]

答案 3 :(得分:0)

这与你要求的不太接近,但是如果你控制了发生器而你不需要在产生值之前“偷看”(并且已经发生任何副作用),你可以使用generator.send方法告诉生成器重复它产生的最后一个值:

>>> def a():
...     for x in (1,2,3):
...             rcvd = yield x
...             if rcvd is not None:
...                     yield x
... 
>>> gen = a()
>>> gen.send("just checking")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can't send non-None value to a just-started generator
>>> gen.next()
1
>>> gen.send("just checking")
1
>>> gen.next()
2
>>> gen.next()
3
>>> gen.next()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration