当前位置:  开发笔记 > 编程语言 > 正文

如何合并两个python迭代器?

如何解决《如何合并两个python迭代器?》经验,为你挑选了5个好方法。

我有两个迭代器,一个list和一个itertools.count对象(即无限值生成器).我想将这两个合并到一个生成的迭代器中,它将在两者之间交替屈服值:

>>> import itertools
>>> c = itertools.count(1)
>>> items = ['foo', 'bar']
>>> merged = imerge(items, c)  # the mythical "imerge"
>>> merged.next()
'foo'
>>> merged.next()
1
>>> merged.next()
'bar'
>>> merged.next()
2
>>> merged.next()
Traceback (most recent call last):
    ...
StopIteration

这样做最简单,最简洁的方法是什么?



1> Pramod..:

发电机可以很好地解决您的问题.

def imerge(a, b):
    for i, j in itertools.izip(a,b):
        yield i
        yield j


您应该添加免责声明 - 这仅在列表a有限时才有效.
在Python 3.0中,zip()的行为类似于itertools.izip().
Claudiu是对的.尝试压缩两个无限生成器 - 最终会耗尽内存.我更喜欢使用itertools.izip而不是zip.然后你随时建立拉链,而不是一次性.你仍然要注意无限循环,但是嘿.

2> David Locke..:

你可以做一些几乎与@Pramod最初建议的事情相似的事情.

def izipmerge(a, b):
  for i, j in itertools.izip(a,b):
    yield i
    yield j

这种方法的优点是,如果a和b都是无限的,你就不会耗尽内存.



3> Tom Swirly..:

我也同意不需要itertools.

但为什么要停在2?

  def tmerge(*iterators):
    for values in zip(*iterators):
      for value in values:
        yield value

从0开始处理任意数量的迭代器.

更新:DOH!一位意见提供者指出,除非所有迭代器的长度相同,否则这将不起作用.

正确的代码是:

def tmerge(*iterators):
  empty = {}
  for values in itertools.izip_longest(*iterators, fillvalue=empty):
    for value in values:
      if value is not empty:
        yield value

是的,我只是用不等长的列表和一个包含{}的列表来尝试它.



4> Claudiu..:

我会做这样的事情.这将是最节省时间和空间的,因为您不会有将对象压缩在一起的开销.这也将工作,如果这两个ab是无限的.

def imerge(a, b):
    i1 = iter(a)
    i2 = iter(b)
    while True:
        try:
            yield i1.next()
            yield i2.next()
        except StopIteration:
            return



5> Claudiu..:

您可以使用zip以及itertools.chain.这在第一个列表有限时才有效:

merge=itertools.chain(*[iter(i) for i in zip(['foo', 'bar'], itertools.count(1))])


但它并不需要那么复杂:`merged = chain.from_iterable(izip(items,count(1)))`会做到这一点.
推荐阅读
无名有名我无名_593
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有