Il itertoolsmodulo integrato di Python ha effettivamente una groupbyfunzione, ma per questo gli elementi da raggruppare devono prima essere ordinati in modo tale che gli elementi da raggruppare siano contigui nell'elenco:
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)
Ora l'input ha questo aspetto:
[('5238761', 'ETH'), ('5349618', 'ETH'), ('962142', 'ETH'), ('7795297', 'ETH'),
('7341464', 'ETH'), ('5594916', 'ETH'), ('1550003', 'ETH'), ('11013331', 'KAT'),
('9843236', 'KAT'), ('9085267', 'NOT'), ('11788544', 'NOT')]
groupbyrestituisce una sequenza di 2-tuple, della forma (key, values_iterator). Quello che vogliamo è trasformare questo in un elenco di dict in cui il "tipo" è la chiave e "elementi" è un elenco degli elementi 0 delle tuple restituite da values_iterator. Come questo:
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)))
Ora resultcontiene il dict desiderato, come indicato nella tua domanda.
Potresti considerare, tuttavia, di creare un singolo dict da questo, con chiave per tipo e ogni valore contenente l'elenco di valori. Nella tua forma attuale, per trovare i valori per un particolare tipo, dovrai scorrere l'elenco per trovare il dict contenente la chiave "type" corrispondente, e quindi ottenere l'elemento "items" da esso. Se usi un singolo dict invece di un elenco di dict a 1 elemento, puoi trovare gli elementi per un particolare tipo con una singola ricerca con chiave nel dict principale. Utilizzando groupby, questo sarebbe simile a:
result = {}
for key,valuesiter in groupby(input, key=sortkeyfn):
result[key] = list(v[0] for v in valuesiter)
resultora contiene questo dict (questo è simile al resdefaultdict intermedio nella risposta di @ KennyTM):
{'NOT': ['9085267', '11788544'],
'ETH': ['5238761', '5349618', '962142', '7795297', '7341464', '5594916', '1550003'],
'KAT': ['11013331', '9843236']}
(Se vuoi ridurlo a una battuta, puoi:
result = dict((key,list(v[0] for v in valuesiter)
for key,valuesiter in groupby(input, key=sortkeyfn))
o usando il nuovo modulo di comprensione dei dettami:
result = {key:list(v[0] for v in valuesiter)
for key,valuesiter in groupby(input, key=sortkeyfn)}
[('11013331', 'red', 'KAT'), ('9085267', 'blue' 'KAT')]dove l'ultimo elemento della tupla è chiave e i primi due come valore. Il risultato dovrebbe essere questo: risultato = [{tipo: 'KAT', elementi: [('11013331', rosso), ('9085267', blu)]}]