2009-08-05 21 views
30

Sto cercando un modo per convertire lista di tuple che assomiglia a questo:PITONE: Conversione lista di tuple in un dizionario

[(1,4),(2,4),(3,4),(4,15),(5,15),(6,23),(7,23),(8,23),(9,15),(10,23),(11,15),(12,15)] 

in un dizionario, dove la chiave: valore coppia sembra In questo modo:

{4:[1,2,3] ,15:[4,5,9,11,12], 23:[6,7,8,10]} 

Il secondo elemento di una tupla diventa un tasto di dizionario. Il primo elemento tupla è assegnato a quel tasto.

Potete mostrarmi come si può fare?

+1

Perché vuoi un elenco di dizionari in cui ogni dizionario ha solo una chiave/valore? Sei sicuro di non voler solo un dizionario? – FogleBird

+0

Sì, avevi ragione FogleBird. Alla fine stavo cercando un dizionario. Grazie per averlo sottolineato ... – elfuego1

+21

A giudicare dal numero di visualizzazioni, la maggior parte delle persone (come me) è arrivata qui cercando come convertire 'myList = [(key1, val1), (key2, val2), ...] 'a un comando:' {chiave1: val1, chiave2: val2 ...} '. Per questo, basta fare 'dict (myList)' – mindthief

risposta

43
>>> from collections import defaultdict 
>>> l= [(1,4),(2,4),(3,4),(4,15),(5,15),(6,23),(7,23),(8,23),(9,15),(10,23),(11,15),(12,15)] 
>>> d= defaultdict(list) 
>>> for v, k in l: 
...  d[k].append(v) 
... 
>>> d 
defaultdict(<type 'list'>, {23: [6, 7, 8, 10], 4: [1, 2, 3], 15: [4, 5, 9, 11, 12]}) 
>>> [ {k:d[k]} for k in sorted(d) ] 
[{4: [1, 2, 3]}, {15: [4, 5, 9, 11, 12]}, {23: [6, 7, 8, 10]}] 
+0

+1 per usare defaultdict. Molto più agevole che chiamare 'setdefault()' ogni volta. –

+0

Love collections.defaultdict. è il mio go-to per un sacco di lavoro. – hughdbrown

2
l = [(1,4),(2,4),(3,4),(4,15),(5,15),(6,23),(7,23),(8,23),(9,15),(10,23),(11,15),(12,15)] 
d = {} 
for v, k in l: 
    d.setdefault(k, []).append(v) 
+0

Copiando il mio uso di setdefault nella tua modifica, ci sono ora meno opzioni per gli elettori da scegliere ... – FogleBird

+2

Non l'ho davvero copiato. Mi sono reso conto che potevo usare setdefault anche dopo averlo postato e aggiornato per posta perché mi piaceva di più. – c089

+0

Nessun problema. Non è sbagliato modificare per aggiungere altre idee in ogni caso, ma in genere è necessario aggiungere più informazioni, non creare una risposta duplicata. Ma capisco che non hai copiato il mio. – FogleBird

2
tuples = [(1,4),(2,4),(3,4),(4,15),(5,15),(6,23),(7,23),(8,23),(9,15),(10,23),(11,15),(12,15)] 
dicts = {} 
for elem in tuples: 
    try: 
     dicts[elem[1]].append(elem[0]) 
    except KeyError: 
     dicts[elem[1]] = [elem[0],] 
+1

Usa decompressione nel ciclo for. E non c'è bisogno di una virgola in un elenco di una sola voce (solo tuple). E l'utilizzo di un'eccezione qui è più corretto in Python rispetto ad altre lingue, ma in questo caso è ancora un po 'sciocco. – FogleBird

+2

L'eccezione non è stupida: è come defaultdict lo fa. Sono d'accordo sul disfare i bagagli però. – xorsyst

12
>>> a = [(1,4),(2,4),(3,4),(4,15),(5,15),(6,23),(7,23),(8,23),(9,15),(10,23),(11,15),(12,15)] 
>>> b = {} 
>>> for i, j in a: 
...  b.setdefault(j, []).append(i) 
... 
>>> b 
{23: [6, 7, 8, 10], 4: [1, 2, 3], 15: [4, 5, 9, 11, 12]} 
>>> 
+0

Grazie mille! – elfuego1

+0

Brillante! Ho appena imparato una nuova operazione dict oggi - setdefault. Questo sistemerà un po 'il mio codice! Saluti. +1 –

+3

@Steve Folly: guarda collections.defaultdict. È ancora meglio –

2

Questo farà:

from collections import defaultdict 

def to_list_of_dicts(list_of_tuples): 
    d = defaultdict(list) 
    for x, y in list_of_tuples: 
     d[y].append(x) 
    return sorted([{x: y} for (x, y) in d.items()]) 
2

Non è elegante ma è semplice

l = [(1,4),(2,4),(3,4),(4,15),(5,15),(6,23),(7,23),(8,23),(9,15),(10,23),(11,15),(12,15)] 
d = dict((k, [i[0] for i in l if i[1] == k]) for k in frozenset(j[1] for j in l)) 

Huzzah!