Date Tags python

who said that ignorance is a bliss didn’t try python :) This is the assignment : you have a list of dictionaries with a field date and you want to group all these dictionaries in a map date -> list of dictionaries with this date.

The first solution that came to my mind was something ugly like :

def group_by_date(qs):
    by_date = {}
    for r in qs :
        l = by_date.get(r['date'],[])
        l.append(r)
        by_date[r['date']] = l
    return by_date

for example :

In [36]: group_by_date([{'date' : 1},{'date' : 2}]) 
Out[36]: {1: [{'date': 1}], 2: [{'date': 2}]}

6 lines of python !!! unacceptable. It hurt my eyes and it is not easy to read. The good people on the #python irc channel adviced me to check the collections.defaultdict and this is actually pretty neat. Now I can write something like

from collections import defaultdict
def group_by_date(qs):
    by_date = defaultdict(list)
    for r in qs :
        by_date[r['date']].append(r)
    return by_date

In [47]: group_by_date([{'date' : 1},{'date' : 2}]) 
Out[47]: defaultdict(<type 'list'>, {1: [{'date': 1}], 2: [{'date': 2}]})

Nice, but still … and we can do better ! itertools.groupby on the rescue :

from itertools import groupby
qs = [{'date' : 1},{'date' : 2}]
[(name, list(group)) for name, group in itertools.groupby(qs, lambda p:p['date'])]

Out[77]: [(1, [{'date': 1}]), (2, [{'date': 2}])]

Ah ! Nirvana :) I’ve to admit the most readable solution is using defaultdict, but this solution using groupby is a wonderful power-tool. If you understand list comprehension, this is a very natural solution to the problem.