<div dir="ltr"><div>Guido said he has mooted this discussion, so it's probably not reaching him.  It took one thousand fewer messages for him to stop following this than with PEP 572, for some reason :-).</div><div><br></div><div>But before putting it on auto-archive, the BDFL said (1) NO GO on getting a new builtin; (2) NO OBJECTION to putting it in itertools.</div><div><br></div><div>My problem with the second idea is that *I* find it very wrong to have something in itertools that does not return an iterator.  It wrecks the combinatorial algebra of the module.</div><div><br></div><div>That said, it's easy to fix... and I believe independently useful.  Just make grouping() a generator function rather than a plain function.  This lets us get an incremental grouping of an iterable.  This can be useful if the iterable is slow or infinite, but the partial groupings are useful in themselves.</div><div><br></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><div><div><font face="monospace, monospace">Python 3.7.0 (default, Jun 28 2018, 07:39:16)</font></div></div></div><div><div><font face="monospace, monospace">[Clang 4.0.1 (tags/RELEASE_401/final)] :: Anaconda, Inc. on darwin</font></div></div><div><div><font face="monospace, monospace">Type "help", "copyright", "credits" or "license" for more information.</font></div></div><div><div><font face="monospace, monospace">>>> from grouping import grouping</font></div></div><div><div><font face="monospace, monospace">>>> grouped = grouping('AbBa', key=str.casefold)</font></div></div><div><div><font face="monospace, monospace">>>> for dct in grouped: print(dct)</font></div></div><div><div><font face="monospace, monospace">...</font></div></div><div><div><font face="monospace, monospace">{'a': ['A']}</font></div></div><div><div><font face="monospace, monospace">{'a': ['A'], 'b': ['b']}</font></div></div><div><div><font face="monospace, monospace">{'a': ['A'], 'b': ['b', 'B']}</font></div></div><div><div><font face="monospace, monospace">{'a': ['A', 'a'], 'b': ['b', 'B']}</font></div></div></blockquote><div><font face="arial, helvetica, sans-serif"><br></font></div><div><font face="arial, helvetica, sans-serif">This isn't so useful for the concrete sequence, but for this it would be great:</font></div><div><font face="arial, helvetica, sans-serif"><br></font></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><font face="monospace, monospace">for grouped in grouping(data_over_wire()):</font></div></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><font face="monospace, monospace">    process_partial_groups(grouped)</font></div></blockquote><font face="arial, helvetica, sans-serif"><div><font face="arial, helvetica, sans-serif"><br></font></div><div><font face="arial, helvetica, sans-serif">The implementation need not and should not rely on "pre-grouping" with itertools.groupby:</font></div><div><font face="arial, helvetica, sans-serif"><br></font></div></font><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div style=""><font style="" face="monospace, monospace"><div style="">def grouping(iterable, key=None):</div><div style="">    groups = {}</div><div style="">    key = key or (lambda x: x)</div><div style="">    for item in iterable:</div><div style="">        groups.setdefault(key(item), []).append(item)</div><div style="">        yield groups</div></font></div></blockquote><font face="arial, helvetica, sans-serif"><br></font><font face="arial, helvetica, sans-serif"><div><font face="arial, helvetica, sans-serif"><div><br></div></font></div></font><font face="arial, helvetica, sans-serif">-- </font><br><div dir="ltr" class="gmail_signature">Keeping medicines from the bloodstreams of the sick; food <br>from the bellies of the hungry; books from the hands of the <br>uneducated; technology from the underdeveloped; and putting <br>advocates of freedom in prisons.  Intellectual property is<br>to the 21st century what the slave trade was to the 16th.<br></div></div>