Что такое идиоматический Python, эквивалентный тегу шаблона Django 'regroup'?
http://docs.djangoproject.com/en/dev/ref/templates/builtins/#regroup
Я могу придумать несколько способов сделать это с помощью циклов, но мне особенно хотелось бы знать, есть ли опрятный однострочный шрифт.
Ответы
Ответ 1
Объедините itertools.groupby
с operator.itemgetter
до получите довольно приятное решение:
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
Предыдущие ответы помогли мне решить мою проблему. В будущем,
если у вас есть некоторые вложенные данные, например
{'city_name': 'City1', 'comp_name': 'Company1', 'name': 'Branch1'}
и вы хотите группировать по городам, а затем по Компании в этом городе, например:
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
Я решил это, сделав это:
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)
Ответ 3
Если источник данных (people
в этом случае) уже отсортирован по ключу, вы можете обойти вызов sorted
:
iter = groupby(people, key=lambda x:x['gender'])
for gender, people in iter:
print '===', gender, '==='
for person in people:
print person
Примечание. Если sorted
является общепринятым словарем, нет никаких гарантий заказа; поэтому вы должны называть sorted
. Здесь я предполагаю, что sorted
является collections.OrderedDict
или какой-либо другой упорядоченной структурой данных.