¿Cómo obtener el primer elemento de una lista de tuplas?
Tengo una lista como la siguiente donde el primer elemento es la identificación y el otro es una cadena:
[(1, u'abc'), (2, u'def')]
Quiero crear una lista de identificadores solo a partir de esta lista de tuplas como se muestra a continuación:
[1,2]
Usaré esta lista, por __in
lo que debe ser una lista de valores enteros.
>>> a = [(1, u'abc'), (2, u'def')]
>>> [i[0] for i in a]
[1, 2]
Utilice la función zip para desacoplar elementos:
>>> inpt = [(1, u'abc'), (2, u'def')]
>>> unzipped = zip(*inpt)
>>> print unzipped
[(1, 2), (u'abc', u'def')]
>>> print list(unzipped[0])
[1, 2]
Editar (@BradSolomon): lo anterior funciona para Python 2.x, donde zip
devuelve una lista.
En Python 3.x, zip
devuelve un iterador y lo siguiente es equivalente a lo anterior:
>>> print(list(list(zip(*inpt))[0]))
[1, 2]
Estaba pensando que podría ser útil comparar los tiempos de ejecución de los diferentes enfoques, así que hice un punto de referencia (usando la biblioteca simple_benchmark ).
I) Punto de referencia que tiene tuplas con 2 elementos
Como es de esperar, seleccionar el primer elemento de las tuplas por índice 0
muestra ser la solución más rápida, muy cercana a la solución de desempaquetado, al esperar exactamente 2 valores.
import operator
import random
from simple_benchmark import BenchmarkBuilder
b = BenchmarkBuilder()
@b.add_function()
def rakesh_by_index(l):
return [i[0] for i in l]
@b.add_function()
def wayneSan_zip(l):
return list(list(zip(*l))[0])
@b.add_function()
def bcattle_itemgetter(l):
return list(map(operator.itemgetter(0), l))
@b.add_function()
def ssoler_upacking(l):
return [idx for idx, val in l]
@b.add_function()
def kederrack_unpacking(l):
return [f for f, *_ in l]
@b.add_arguments('Number of tuples')
def argument_provider():
for exp in range(2, 21):
size = 2**exp
yield size, [(random.choice(range(100)), random.choice(range(100))) for _ in range(size)]
r = b.run()
r.plot()
II) Punto de referencia que tiene tuplas con 2 o más elementos
import operator
import random
from simple_benchmark import BenchmarkBuilder
b = BenchmarkBuilder()
@b.add_function()
def kederrack_unpacking(l):
return [f for f, *_ in l]
@b.add_function()
def rakesh_by_index(l):
return [i[0] for i in l]
@b.add_function()
def wayneSan_zip(l):
return list(list(zip(*l))[0])
@b.add_function()
def bcattle_itemgetter(l):
return list(map(operator.itemgetter(0), l))
@b.add_arguments('Number of tuples')
def argument_provider():
for exp in range(2, 21):
size = 2**exp
yield size, [tuple(random.choice(range(100)) for _
in range(random.choice(range(2, 100)))) for _ in range(size)]
from pylab import rcParams
rcParams['figure.figsize'] = 12, 7
r = b.run()
r.plot()
¿Te refieres a algo como esto?
new_list = [ seq[0] for seq in yourlist ]
Lo que realmente tienes es una lista de tuple
objetos, no una lista de conjuntos (como implicaba tu pregunta original). Si en realidad es una lista de conjuntos, entonces no hay un primer elemento porque los conjuntos no tienen orden.
Aquí he creado una lista plana porque generalmente parece más útil que crear una lista de tuplas de 1 elemento. Sin embargo, puedes crear fácilmente una lista de tuplas de 1 elemento simplemente reemplazándolas seq[0]
con (seq[0],)
.