How do I merge two python iterators?

前端 未结 13 1174
花落未央
花落未央 2020-12-06 09:29

I have two iterators, a list and an itertools.count object (i.e. an infinite value generator). I would like to merge these two into a resulting ite

相关标签:
13条回答
  • Using itertools.izip(), instead of zip() as in some of the other answers, will improve performance:

    As "pydoc itertools.izip" shows: "Works like the zip() function but consumes less memory by returning an iterator instead of a list."

    Itertools.izip will also work properly even if one of the iterators is infinite.

    0 讨论(0)
  • 2020-12-06 10:03

    You can use zip as well as itertools.chain. This will only work if the first list is finite:

    merge=itertools.chain(*[iter(i) for i in zip(['foo', 'bar'], itertools.count(1))])
    
    0 讨论(0)
  • 2020-12-06 10:04

    You can do something that is almost exaclty what @Pramod first suggested.

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

    The advantage of this approach is that you won't run out of memory if both a and b are infinite.

    0 讨论(0)
  • 2020-12-06 10:08

    I prefer this other way which is much more concise:

    iter = reduce(lambda x,y: itertools.chain(x,y), iters)
    
    0 讨论(0)
  • 2020-12-06 10:12

    I also agree that itertools is not needed.

    But why stop at 2?

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

    handles any number of iterators from 0 on upwards.

    UPDATE: DOH! A commenter pointed out that this won't work unless all the iterators are the same length.

    The correct code is:

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

    and yes, I just tried it with lists of unequal length, and a list containing {}.

    0 讨论(0)
  • 2020-12-06 10:14

    A generator will solve your problem nicely.

    def imerge(a, b):
        for i, j in itertools.izip(a,b):
            yield i
            yield j
    
    0 讨论(0)
提交回复
热议问题