[Django]-What's the idiomatic Python equivalent to Django's 'regroup' template tag?

36👍

Combine itertools.groupby with operator.itemgetter to get a pretty nice solution:

from operator import itemgetter
from itertools import groupby

key = itemgetter('gender')
iter = groupby(sorted(people, key=key), key=key)

for gender, people in iter:
    print '===', gender, '==='
    for person in people:
        print person

2👍

If the source of data (people in this case) is already sorted by the key, you can bypass the sorted call:

iter = groupby(people, key=lambda x:x['gender'])
for gender, people in iter:
    print '===', gender, '==='
    for person in people:
        print person

Note: If sorted is a common dictionary, there are no guarantees of order; therefore you must call sorted. Here I’m supposing that sorted is a collections.OrderedDict or some other kind of ordered data structure.

1👍

Previous answers helped me to solve my problem. For future reference,
if you have some nested data like

{‘city_name’: ‘City1’, ‘comp_name’: ‘Company1’, ‘name’: ‘Branch1’}

and you want to group by City and then by Company in that city like:

City1
 Company 1
   Branch 1
   Branch 2
 Company 2
   Branch 1
 Company 3
   Branch 1
City2
 Company 2
   Branch 1
 Company 3
   Branch 1
   Branch 2
City3
 Company 1
   Branch 1
 Company 2
   Branch 1
   Branch 2

I solved it by doing this:

key = itemgetter('city_name')    
iter = groupby(queryset, key=key) # assuming queryset is already sorted by city_name

for key, group in iter:
    print(key)
    key2 = itemgetter('company_name')
    iter2 = groupby(sorted(group, key=key2), key=key2) # now we must sort by company_name
    for comp, branch in iter2:
        print(comp)
        for b in branch:
            print(b)

Leave a comment