Why does `zip` seem to consume` groupby` iterable?

So splitting a list with is itertools.groupby()pretty simple.

>>> import itertools as it
>>> iterable = it.groupby([1, 2, 3, 4, 5, 2, 3, 4, 2], lambda p: p==2)
>>> for x, y in iterable:
...     print(x, list(y))
...     next(iterable)
False [1]
False [3, 4, 5]
False [3, 4]

It works as expected. But using the common python idiom zipto have the iterator step over 2 times several times seems to break things.

>>> iterable = it.groupby([1, 2, 3, 4, 5, 2, 3, 4, 2], lambda p: p==2)
>>> for (x, y), _ in zip(iterable, iterable):
...     print(x, list(y))
False []
False []
False []

The addition print(y)shows the expected nested iterative <itertools._grouper object at 0xXXXXXXXX>, but I obviously didn’t understand why the object is grouperempty. Can anyone shed some light?

I get an even stranger result if I have an uneven list and use itertools.zip_longest:

>>> iterable = it.groupby([1, 2, 3, 4, 5, 2, 3, 4], lambda p: p==2)
>>> for (x, y), _ in it.zip_longest(iterable, iterable, fillvalue=None):
...     print(x, list(y))
False []
False []
False [4]

Update . A simple fix is ​​to use itertools.islice():

>>> iterable = it.groupby([1, 2, 3, 4, 5, 2, 3, 4, 2], lambda p: p==2)
>>> for x, y in it.islice(iterable, None, None, 2):
...     print(x, list(y))
False [1]
False [3, 4, 5]
False [3, 4]
+4
2

groupby ,

, groupby(). , groupby() , .

zip ((key, group), (key, group)), groupby , . , :

iterable = ((key, list(group)) for (key, group) in it.groupby([1, 2, 3, 4, 5, 2, 3, 4, 2], lambda p: p==2))
for (x, y), _ in zip(iterable, iterable):
    print(x, y)
+6

, itertools.groupby, _grouper.

:

>>> iterable = it.groupby([1, 2, 3, 4, 5, 2, 3, 4, 2], lambda p: p==2)
>>> for (x, y), (x2, y2) in zip(iterable, iterable):
...     print(x2, list(y2))
True [2]
True [2]
True [2]

:

, groupby(). , groupby() , . , , , .

, (x, y), _ in zip(iterable, iterable), 2 ( _), ( x, y) !

+2

Source: https://habr.com/ru/post/1665036/


All Articles