This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author serhiy.storchaka
Recipients Matt Gilson, mgilson, rhettinger, serhiy.storchaka
Date 2017-05-12.09:18:30
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1494580710.94.0.0385042664427.issue30346@psf.upfronthosting.co.za>
In-reply-to
Content
Does it make sense using a grouper after advancing the groupby iterator? Currently it is possible by accident:

>>> from itertools import groupby, count
>>> it = groupby(count(), lambda i: (i//10)%2)
>>> _, even = next(it)
>>> _, odd = next(it)
>>> print(list(even))
[]
>>> print(list(odd))
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> print(list(even))
[20, 21, 22, 23, 24, 25, 26, 27, 28, 29]
>>> print(list(odd))
[30, 31, 32, 33, 34, 35, 36, 37, 38, 39]
>>> print(list(even))
[40, 41, 42, 43, 44, 45, 46, 47, 48, 49]

But I think that it would be more consistent to implement one of following variant:

1. Invalidate groupers after creating a new grouper. There should be only one valid grouper related to the groupby object. Using of invalid grouper should raise either StopIteration or RuntimeError.

>>> it = groupby(count(), lambda i: (i//10)%2)
>>> _, even = next(it)
>>> _, odd = next(it)
>>> print(list(even))
[]
>>> print(list(odd))
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> print(list(even))
[]
>>> print(list(odd))
[]

or

>>> it = groupby(count(), lambda i: (i//10)%2)
>>> _, even = next(it)
>>> _, odd = next(it)
>>> print(list(even))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
RuntimeError
>>> print(list(odd))
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> print(list(even))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
RuntimeError
>>> print(list(odd))
[]

2. Duplicate the source iterator using tee() when create a new grouper. All groupers can be used independently from the groupby object and other groupers.

>>> it = groupby(range(100), lambda i: (i//10)%2)
>>> _, even = next(it)
>>> _, odd = next(it)
>>> _ = list(it)  # exhaust the source iterator
>>> print(list(even))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> print(list(odd))
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> print(list(even))
[]
>>> print(list(odd))
[]

I think resolving this issue will also fix issue30347.
History
Date User Action Args
2017-05-12 09:18:30serhiy.storchakasetrecipients: + serhiy.storchaka, rhettinger, mgilson, Matt Gilson
2017-05-12 09:18:30serhiy.storchakasetmessageid: <1494580710.94.0.0385042664427.issue30346@psf.upfronthosting.co.za>
2017-05-12 09:18:30serhiy.storchakalinkissue30346 messages
2017-05-12 09:18:30serhiy.storchakacreate