lista a la conversión del diccionario con múltiples valores por clave?

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ían múltiples 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?

 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 código predeterminado temporal con listas como valores, que se convertirán en tuplas en la última línea. De esta manera, se agrega a las listas y no se recrean las tuplas en el ciclo principal.

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 (explicando las exportaciones):

 dict(functools.reduce(lambda x, d: x[d[0]].append(d[1]) or x, l, collections.defaultdict(list))) 

Tenga en cuenta que reducir se ha movido a functools y que las lambdas ya no aceptan tuplas. Esta versión aún funciona en 2.6 y 2.7.

Usando 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 

¿Las claves ya están ordenadas en la lista de entrada? Si ese es el caso, tienes 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',)}