Группировать список диктовок с несколькими ключами не работает, даже если я использовал отсортированный ранее
У меня есть список таких словарей:
a = [
{'user_id':'111','clean_label':'VIR SEPA'},
{'user_id':'112','clean_label':'VIR SEPA'},
{'user_id':'111','clean_label':'VIR SEPA'},
]
и я хочу, чтобы:
a = [
[
{'user_id':'111','clean_label':'VIR SEPA'},
{'user_id':'111','clean_label':'VIR SEPA'}
],
[
{'user_id':'112','clean_label':'VIR SEPA'}
]
]
Я пробовал с sorted и groupby из itertools следующим образом:
sorted(a,key=lambda x: (x['user_id'],x['clean_label']))
[ [tr for tr in tr_per_user_id_clean_label] for key, tr_per_user_id_clean_label in itertools.groupby(a, key=lambda x: (x['user_id'], x['clean_label'])) ]
но я понимаю, что:
[[{'user_id': '111', 'clean_label': 'VIR SEPA'}],
[{'user_id': '112', 'clean_label': 'VIR SEPA'}],
[{'user_id': '111', 'clean_label': 'VIR SEPA'}]]
Кто-нибудь может мне помочь ??
* Редактировать: когда я сортирую:
[{'user_id': '111', 'clean_label': 'VIR SEPA'},
{'user_id': '111', 'clean_label': 'VIR SEPA'},
{'user_id': '112', 'clean_label': 'VIR SEPA'}]
1 ответ
itertools.groupby
на самом деле не идеальный инструмент для этого.
Вы можете достичь своей цели со сложностью O(n), используяdefaultdict
(по сравнению с O(n log n) сgroupby
как вам нужно отсортировать):
from collections import defaultdict
dd = defaultdict(list)
for d in a:
dd[(d['user_id'], d['clean_label'])].append(d)
out = list(dd.values())
альтернатива сsetdefault
:
dd = {}
for d in a:
dd.setdefault((d['user_id'], d['clean_label']), []).append(d)
out = list(dd.values())
выход:
[[{'user_id': '111', 'clean_label': 'VIR SEPA'},
{'user_id': '111', 'clean_label': 'VIR SEPA'}],
[{'user_id': '112', 'clean_label': 'VIR SEPA'}]]
Если вывод необходимо отсортировать по user_id:
out = sorted(dd.values(),
key=lambda x: (int(x[0]['user_id']), int(x[0]['clean_label'])))