On 1 July 2018 at 15:18, Chris Barker via Python-ideas <python-ideas@python.org> wrote: > On Fri, Jun 29, 2018 at 10:53 AM, Michael Selik <m...@selik.org> wrote: >> >> I've drafted a PEP for an easier way to construct groups of elements from >> a sequence. https://github.com/selik/peps/blob/master/pep-9999.rst >> > I'm really warming to the: > > Alternate: collections.Grouping > > version -- I really like this as a kind of custom mapping, rather than "just > a function" (or alternate constructor) -- and I like your point that it can > have a bit of functionality built in other than on construction. > > But I think it should be more like the other collection classes -- i.e. a > general purpose class that can be used for grouping, but also used more > general-purpose-y as well. That way people can do their "custom" stuff (key > function, etc.) with comprehensions. > > The big differences are a custom __setitem__: > > def __setitem__(self, key, value): > self.setdefault(key, []).append(value) > > And the __init__ and update would take an iterable of (key, value) pairs, > rather than a single sequence. > > This would get away from the itertools.groupby approach, which I find kinda > awkward: > > * How often do you have your data in a single sequence? > > * Do you need your keys (and values!) to be sortable???) > > * Do we really want folks to have to be writing custom key functions and/or > lambdas for really simple stuff? > > * and you may need to "transform" both your keys and values > > I've enclosed an example implementation, borrowing heavily from Michael's > code. > > The test code has a couple examples of use, but I'll put them here for the > sake of discussion. > > Michael had: > > Grouping('AbBa', key=c.casefold)) > > with my code, that would be: > > Grouping(((c.casefold(), c) for c in 'AbBa')) > > Note that the key function is applied outside the Grouping object, it > doesn't need to know anything about it -- and then users can use an > expression in a comprehension rather than a key function. > > This looks a tad clumsier with my approach, but this is a pretty contrived > example -- in the more common case [*], you'd be writing a bunch of lambdas, > etc, and I'm not sure there is a way to get the values customized as well, > if you want that. (without applying a map later on) > > Here is the example that the OP posted that kicked off this thread: > > In [37]: student_school_list = [('Fred', 'SchoolA'), > ...: ('Bob', 'SchoolB'), > ...: ('Mary', 'SchoolA'), > ...: ('Jane', 'SchoolB'), > ...: ('Nancy', 'SchoolC'), > ...: ] > > In [38]: Grouping(((item[1], item[0]) for item in student_school_list)) > Out[38]: Grouping({'SchoolA': ['Fred', 'Mary'], > 'SchoolB': ['Bob', 'Jane'], > 'SchoolC': ['Nancy']})
Unpacking and repacking the tuple would also work: Grouping(((school, student) for student, school in student_school_list)) Cheers, Nick. -- Nick Coghlan | ncogh...@gmail.com | Brisbane, Australia _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/