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

17 投票
4 回答
16750 浏览
提问于 2025-04-15 13:32

我有一个程序,内容如下:

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 个回答

4

一般来说,迭代器的设计是为了只读的,也就是说,你不能随便去改动它,否则就会出问题。

另外,你可以试着反向读取这个迭代器,然后把它加到元素的末尾(其实那是开始的位置 :))?

42

你在寻找 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]
15

Python中的迭代器功能比较有限,比如不能直接“添加”元素之类的。如果你想要这样的功能,就需要把通用的迭代器放在一个“包装器”里,来增加这些功能。比如:

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.x版本中则是必须的(要用next(self.it)代替self.it.next(),并且要定义__next__而不是next)。

编辑:提问者现在说他们需要的是“提前查看而不消耗”。虽然包装器仍然是最好的选择,但还有另一种方法:

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

这个方法不会让o前进(记得在你决定要前进的时候再让它前进哦;-)。

撰写回答