Why does zip() drop the values of my generator?

前端 未结 2 1877
死守一世寂寞
死守一世寂寞 2021-01-02 04:31

I was writing an answer to this question when noticed that my simple implementation didn\'t produce correct results. While hunting down the bug, I noticed the following:

相关标签:
2条回答
  • 2021-01-02 05:17

    Your self-answer is exactly right, and presents a very good solution -- if one of the arguments to zip is always shorter than the other. However, in situations where you don't know which will be shorter, you might find islice useful. islice also provides an easy workaround if you want the first item in your tuples to be from your generator. In your case, you could do this:

    >>> import itertools
    >>> gen = itertools.cycle(('a', 'b', 'c'))
    >>> seq = range(3)
    >>> zip(itertools.islice(gen, len(seq)), seq)
    [('a', 0), ('b', 1), ('c', 2)]
    >>> zip(itertools.islice(gen, len(seq)), seq)
    [('a', 0), ('b', 1), ('c', 2)]
    

    Your answer is probably better in this case -- it's certainly simpler -- but I thought I'd add this as a supplement.

    0 讨论(0)
  • 2021-01-02 05:22

    This happens because zip evaluates iterators from left to right, meaning that, after three steps, it calls next() on gen and only then on iter(range(3)) (or something like that) and encounters a StopIteration. To get around this, use the shorter (finite) iterable as the left-most argument:

    In [8]: zip(range(3), gen)
    0
    1
    2
    Out[8]: [(0, 0), (1, 1), (2, 2)]
    
    0 讨论(0)
提交回复
热议问题