Вбудований itertools
модуль Python насправді має groupby
функцію, але для цього елементи, які потрібно згрупувати, спочатку повинні бути відсортовані таким чином, щоб елементи, які слід згрупувати, були суміжними у списку:
from operator import itemgetter
sortkeyfn = itemgetter(1)
input = [('11013331', 'KAT'), ('9085267', 'NOT'), ('5238761', 'ETH'),
('5349618', 'ETH'), ('11788544', 'NOT'), ('962142', 'ETH'), ('7795297', 'ETH'),
('7341464', 'ETH'), ('9843236', 'KAT'), ('5594916', 'ETH'), ('1550003', 'ETH')]
input.sort(key=sortkeyfn)
Тепер вхід виглядає так:
[('5238761', 'ETH'), ('5349618', 'ETH'), ('962142', 'ETH'), ('7795297', 'ETH'),
('7341464', 'ETH'), ('5594916', 'ETH'), ('1550003', 'ETH'), ('11013331', 'KAT'),
('9843236', 'KAT'), ('9085267', 'NOT'), ('11788544', 'NOT')]
groupby
повертає послідовність 2-х кортезів форми (key, values_iterator)
. Ми хочемо перетворити це на список диктовок, де "тип" є ключем, а "items" - це список 0-х елементів кортежів, повернутих значень_iterator. Подобається це:
from itertools import groupby
result = []
for key,valuesiter in groupby(input, key=sortkeyfn):
result.append(dict(type=key, items=list(v[0] for v in valuesiter)))
Тепер result
міститься бажаний вислів, як зазначено у вашому запитанні.
Ви можете врахувати, що просто скласти з цього один диктат, введений за типом і кожне значення, що містить список значень. У вашій поточній формі, щоб знайти значення для певного типу, вам доведеться перебрати список, щоб знайти дік, що містить відповідний ключ 'type', а потім отримати з нього елемент 'items'. Якщо ви використовуєте один дикт замість списку однокласних диктовок, ви можете знайти елементи для певного типу за допомогою одного клавішного пошуку в основний дікт. Використовуючи groupby
це, виглядатиме так:
result = {}
for key,valuesiter in groupby(input, key=sortkeyfn):
result[key] = list(v[0] for v in valuesiter)
result
тепер містить цей дикт (це схоже на проміжний res
вирок за замовчуванням у відповіді @ KennyTM):
{'NOT': ['9085267', '11788544'],
'ETH': ['5238761', '5349618', '962142', '7795297', '7341464', '5594916', '1550003'],
'KAT': ['11013331', '9843236']}
(Якщо ви хочете зменшити це до однолінійного, ви можете:
result = dict((key,list(v[0] for v in valuesiter)
for key,valuesiter in groupby(input, key=sortkeyfn))
або використовуючи новомодну форму розуміння дикту:
result = {key:list(v[0] for v in valuesiter)
for key,valuesiter in groupby(input, key=sortkeyfn)}
[('11013331', 'red', 'KAT'), ('9085267', 'blue' 'KAT')]
де останній елемент кортежа є ключовим, а перші два - значеннями. Результат повинен бути таким: result = [{type: 'KAT', items: [('11013331', червоний), ('9085267', синій)]}}]