¿Cómo obtener el primer elemento de una lista de tuplas?

Resuelto wasimbhalli asked hace 12 años • 17 respuestas

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 __inlo que debe ser una lista de valores enteros.

wasimbhalli avatar Aug 27 '12 19:08 wasimbhalli
Aceptado
>>> a = [(1, u'abc'), (2, u'def')]
>>> [i[0] for i in a]
[1, 2]
Rakesh avatar Aug 27 '2012 13:08 Rakesh

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 zipdevuelve una lista.

En Python 3.x, zipdevuelve un iterador y lo siguiente es equivalente a lo anterior:

>>> print(list(list(zip(*inpt))[0]))
[1, 2]
WayneSan avatar Jul 08 '2015 15:07 WayneSan

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 ingrese la descripción de la imagen aquí

Como es de esperar, seleccionar el primer elemento de las tuplas por índice 0muestra 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 ingrese la descripción de la imagen aquí

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()
kederrac avatar Feb 18 '2020 12:02 kederrac

¿Te refieres a algo como esto?

new_list = [ seq[0] for seq in yourlist ]

Lo que realmente tienes es una lista de tupleobjetos, 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],).

mgilson avatar Aug 27 '2012 12:08 mgilson