236 votes

Comment obtenir le premier élément d'une liste de tuples ?

J'ai une liste comme ci-dessous où le premier élément est l'id et l'autre est une chaîne de caractères :

[(1, u'abc'), (2, u'def')]

Je veux créer une liste d'identifiants uniquement à partir de cette liste de tuples comme ci-dessous :

[1,2]

Je vais utiliser cette liste dans __in il doit donc s'agir d'une liste de valeurs entières.

348voto

Rakesh Points 2644
>>> a = [(1, u'abc'), (2, u'def')]
>>> [i[0] for i in a]
[1, 2]

98voto

WayneSan Points 979

Utilisez la fonction zip pour découpler les éléments :

>>> 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) : Ce qui précède fonctionne pour Python 2.x, dans lequel zip renvoie une liste.

Dans Python 3.x, zip renvoie un itérateur et ce qui suit est équivalent à ce qui précède :

>>> print(list(list(zip(*inpt))[0]))
[1, 2]

27voto

kederrac Points 15339

J'ai pensé qu'il pourrait être utile de comparer les temps d'exécution des différentes approches et j'ai donc réalisé un benchmark (en utilisant le logiciel simple_benchmark bibliothèque)

I) Benchmark ayant des tuples avec 2 éléments enter image description here

Comme on peut s'y attendre, pour sélectionner le premier élément des tuples par indice 0 s'avère être la solution la plus rapide et très proche de la solution de déballage en attendant exactement 2 valeurs

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) Benchmark ayant des tuples avec 2 éléments ou plus enter image description here

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()

24voto

mgilson Points 92954

Vous voulez dire quelque chose comme ça ?

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

Ce que vous avez en fait, c'est une liste de tuple et non une liste d'ensembles (comme votre question initiale le laissait entendre). S'il s'agit effectivement d'une liste d'ensembles, alors il n'y a pas de premier élément parce que les ensembles n'ont pas d'ordre.

Ici, j'ai créé une liste plate parce que cela semble généralement plus utile que de créer une liste de tuples à un élément. Cependant, vous pouvez facilement créer une liste de tuples à 1 élément en remplaçant simplement seq[0] con (seq[0],) .

18voto

bcattle Points 475

C'est ce que operator.itemgetter est pour.

>>> a = [(1, u'abc'), (2, u'def')]
>>> import operator
>>> b = map(operator.itemgetter(0), a)
>>> b
[1, 2]

El itemgetter déclaration renvoie une fonction qui renvoie l'élément à l'index que vous spécifiez. C'est exactement la même chose que d'écrire

>>> b = map(lambda x: x[0], a)

Mais je trouve que itemgetter est plus clair et plus explicite .

C'est pratique pour faire des déclarations de tri compactes. Par exemple,

>>> c = sorted(a, key=operator.itemgetter(0), reverse=True)
>>> c
[(2, u'def'), (1, u'abc')]

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X