La lista de Python de tuplas combina el segundo elemento con un primer elemento único

Dada una lista de tuplas como tal:

a = [ ( "x", 1, ), ( "x", 2, ), ( "y", 1, ), ( "y", 3, ), ( "y", 4, ) ] 

¿Cuál sería la forma más fácil de filtrar por primer elemento único y fusionar el segundo elemento? Una salida como esa sería deseada.

 b = [ ( "x", 1, 2 ), ( "y", 1, 3, 4 ) ] 

Gracias,

Puedes usar un defaultdict :

 >>> from collections import defaultdict >>> d = defaultdict(tuple) >>> a = [('x', 1), ('x', 2), ('y', 1), ('y', 3), ('y', 4)] >>> for tup in a: ... d[tup[0]] += (tup[1],) ... >>> [tuple(x for y in i for x in y) for i in d.items()] [('y', 1, 3, 4), ('x', 1, 2)] 
 >>> a = [("x", 1,), ("x", 2,), ("y", 1,), ("y", 3,), ("y", 4,)] >>> d = {} >>> for k, v in a: ... d.setdefault(k, [k]).append(v) >>> b = map(tuple, d.values()) >>> b [('y', 1, 3, 4), ('x', 1, 2)] 

Esto es lo que se me ocurrió:

 [tuple(list(el) + [q[1] for q in a if q[0]==el]) for el in set([q[0] for q in a])] 

Además de las respuestas anteriores, otra de una sola línea:

 >>> a = [ ( "x", 1, ), ( "x", 2, ), ( "y", 1, ), ( "y", 3, ), ( "y", 4, ) ] >>> from itertools import groupby >>> [(key,) + tuple(elem for _, elem in group) for key, group in groupby(a, lambda pair: pair[0])] [('x', 1, 2), ('y', 1, 3, 4)] 

Una forma es usando la expresión de comprensión de lista con itertools.groupby , itertools.chain y operator.itemgetter como:

 >>> from itertools import groupby, chain >>> from operator import itemgetter >>> my_list = [ ( "x", 1, ), ( "x", 2, ), ( "y", 1, ), ( "y", 3, ), ( "y", 4, ) ] >>> [set(chain(*i)) for _, i in groupby(sorted(my_list), key=itemgetter(0))] [set(['x', 2, 1]), set(['y', 1, 3, 4])] 

Nota: los set no están ordenados en la naturaleza, por lo que no conservarán la posición de los elementos. No utilice set si la posición importa.