python - listas - lista a conversión de diccionario con múltiples valores por clave?
imprimir clave diccionario python (4)
Tengo una lista de Python que contiene pares de clave / valor:
l=[ [1, ''A''], [1, ''B''], [2, ''C''] ]
Quiero convertir la lista en un diccionario, donde se agregarán varios valores por clave en una tupla:
{ 1:(''A'', ''B''), 2:(''C'',) }
La solución iterativa es trivial:
l=[ [1, ''A''], [1, ''B''], [2, ''C''] ]
d={}
for pair in l:
if d.has_key(pair[0]):
d[pair[0]]=d[pair[0]]+tuple(pair[1])
else:
d[pair[0]]=tuple(pair[1])
print d
{1: (''A'', ''B''), 2: (''C'',)}
¿Hay una solución Pythonic más elegante para esta tarea?
¿Están las claves ya ordenadas en la lista de entrada? Si ese es el caso, tiene una solución funcional:
import itertools
lst = [(1, ''A''), (1, ''B''), (2, ''C'')]
dct = dict((key, tuple(v for (k, v) in pairs))
for (key, pairs) in itertools.groupby(lst, lambda pair: pair[0]))
print dct
# {1: (''A'', ''B''), 2: (''C'',)}
Este método es relativamente eficiente y bastante compacto:
reduce(lambda x, (k,v): x[k].append(v) or x, l, defaultdict(list))
En Python3 esto se convierte (haciendo que las exportaciones sean explícitas):
dict(functools.reduce(lambda x, d: x[d[0]].append(d[1]) or x, l, collections.defaultdict(list)))
Tenga en cuenta que reduce se ha movido a functools y que las lambdas ya no aceptan tuplas. Esta versión todavía funciona en 2.6 y 2.7.
Usar listas en lugar de tuplas como valores dict:
l=[ [1, ''A''], [1, ''B''], [2, ''C''] ]
d={}
for key, val in l:
d.setdefault(key, []).append(val)
print d
from collections import defaultdict
d1 = defaultdict(list)
for k, v in l:
d1[k].append(v)
d = dict((k, tuple(v)) for k, v in d1.iteritems())
d
contiene ahora {1: (''A'', ''B''), 2: (''C'',)}
d1
es un fallo de pago temporal con listas como valores, que se convertirán en tuplas en la última línea. De esta forma, se agrega a las listas y no se reproducen las tuplas en el ciclo principal.