di Python modulo incorporato itertools
in realtà ha una funzione groupby
che si potrebbe usare, ma gli elementi per essere raggruppati devono prima essere ordinati in modo tale che gli elementi che devono essere raggruppati sono contigui nella lista:
sortkeyfn = key=lambda s:s[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 d'ingresso si presenta come:
[('5238761', 'ETH'), ('5349618', 'ETH'), ('962142', 'ETH'), ('7795297', 'ETH'),
('7341464', 'ETH'), ('5594916', 'ETH'), ('1550003', 'ETH'), ('11013331', 'KAT'),
('9843236', 'KAT'), ('9085267', 'NOT'), ('11788544', 'NOT')]
groupby
restituisce una sequenza di 2-tuple, della forma (key, values_iterator)
. Quello che vogliamo è trasformarlo in una lista di dict in cui il 'tipo' è la chiave, e 'items' è una lista degli 0'th elementi 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 result
contiene tua dict desiderato, come affermato nella sua interrogazione.
Si potrebbe prendere in considerazione, tuttavia, solo facendo un singolo dettato da questo, digitato per tipo, e ogni valore contenente l'elenco dei 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 si utilizza un singolo dict invece di un elenco di dict 1 elemento, è possibile trovare gli elementi per un determinato tipo con una singola ricerca con chiave nel dettato principale.Utilizzando groupby
, questo sarebbe simile:
result = {}
for key,valuesiter in groupby(input, key=sortkeyfn):
result[key] = list(v[0] for v in valuesiter)
result
ora contiene questa dict (questo è simile a quello intermedio res
defaultdict in @ di KennyTM risposta):
{'NOT': ['9085267', '11788544'],
'ETH': ['5238761', '5349618', '962142', '7795297', '7341464', '5594916', '1550003'],
'KAT': ['11013331', '9843236']}
(Se si vuole ridurre questo per una battuta, è possibile:
result = dict((key,list(v[0] for v in valuesiter)
for key,valuesiter in groupby(input, key=sortkeyfn))
oppure utilizzando il modulo dict-comprensione diavolerie:
result = {key:list(v[0] for v in valuesiter)
for key,valuesiter in groupby(input, key=sortkeyfn)}
Come può essere fatto se la tupla ingresso ha una chiave e due o più valori, in questo modo: '[('11.013.331', 'rosso' , 'KAT'), ('9085267', 'blue' 'KAT')] 'dove l'ultimo elemento della tupla è la chiave e i primi due come valore. Il risultato dovrebbe essere questo: result = [{ type: 'KAT', articoli: [('11013331', rosso), ('9085267', blu)]}] – user1144616