Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Loop through generator two items at a time

I have defined a generator that yields log entries from Elasticsearch:

def gen():
    ....
    for hit in results:
        yield hit

How can I loop through two elements at the same time? Something in the lines of:

for one, two in gen():
    ...

By two elements I mean this: A, B, B, C, ..., Y, Z (for a generated list of A, B, ..., Y, Z).

like image 809
linkyndy Avatar asked May 08 '17 08:05

linkyndy


People also ask

Can you iterate through a generator?

Simply speaking, a generator is a function that returns an object (iterator) which we can iterate over (one value at a time).

How do you iterate through a generator object?

You need to call next() or loop through the generator object to access the values produced by the generator expression. When there isn't the next value in the generator object, a StopIteration exception is thrown. A for loop can be used to iterate the generator object.

Which keyword can we use to make an ordinary Python function into a generator?

In the above example, the mygenerator() function is a generator function. It uses yield instead of return keyword. So, this will return the value against the yield keyword each time it is called. However, you need to create an iterator for this function, as shown below.

How do Python generators work?

A Python generator is a function that produces a sequence of results. It works by maintaining its local state, so that the function can resume again exactly where it left off when called subsequent times. Thus, you can think of a generator as something like a powerful iterator.


1 Answers

This answer assumes you want non-overlapping pairs. You can do this via zip() because the iterator is consumed:

for one, two in zip(gen, gen):
    # do something

Example:

>>> gen = (x for x in range(5))
>>> for one, two in zip(gen, gen): print(one,two)
... 
0 1
2 3

Note, as timgeb commented, you should use itertools.zip_longest if you have an uneven number of elements and you want the last one with a fill value, for example:

>>> gen = (x for x in range(5))
>>> for one, two in zip_longest(gen, gen): print(one, two)
... 
0 1
2 3
4 None
like image 186
Chris_Rands Avatar answered Oct 14 '22 18:10

Chris_Rands