I feel like Python ought to have a built-in to do this. Take a list of items 
and turn them into a dictionary mapping keys to a list of items with that key 
in common.

It's easy enough to do:

    # using defaultdict
    lookup = collections.defaultdict(list)
    for item in items:
        lookup[key(item)].append(item)
    
    # or, using plain dict
    lookup = {}
    for item in items:
        lookup.setdefault(key(item), []).append(item)

But this is frequent enough of a use case that a built-in function would be 
nice. I could implement it myself, as such:

    def grouped(iterable, key):
        result = {}
        for item in iterable:
            result.setdefault(key(item), []).append(item)
        return result
    
    lookup = grouped(items, key)

This is different than `itertools.groupby` in a few important ways. To get the 
same result from `groupby`, you'd have to do this, which is a little ugly:

    lookup = dict((k, list(v)) for k, v in groupby(sorted(items, key=key), key))

Some examples:


    >>> items = range(10)
    >>> grouped(items, lambda x: x % 2)
    {0: [0, 2, 4, 6, 8], 1: [1, 3, 5, 7, 9]}
    
    >>> items = 'hello stack overflow how are you'.split()
    >>> grouped(items, len)
    {8: ['overflow'], 3: ['how', 'are', 'you'], 5: ['hello', 'stack']}

Is there a better way?
-- 
http://mail.python.org/mailman/listinfo/python-list

Reply via email to