J'ai une liste comme ci-dessous où le premier élément est l'identifiant et l'autre est une chaîne:
[(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.
>>> a = [(1, u'abc'), (2, u'def')]
>>> [i[0] for i in a]
[1, 2]
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]
Edit (@BradSolomon): Ce qui précède fonctionne pour Python 2.x, où 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]
voulez-vous dire quelque chose comme ça?
new_list = [ seq[0] for seq in yourlist ]
Ce que vous avez réellement est une liste d'objets Tuple
, pas une liste d'ensembles (comme l'indiquait votre question initiale). S'il s'agit en fait d'une liste d'ensembles, alors il n'y a pas de premier élément car les ensembles n'ont pas d'ordre.
Ici, j'ai créé une liste non hiérarchique car cela semble généralement plus utile que de créer une liste de tuples à 1 élément. Cependant, vous pouvez facilement créer une liste de nuplets à 1 élément en remplaçant simplement seq[0]
par (seq[0],)
.
Vous pouvez utiliser "Décompresser les tuples":
>>> my_list = [(1, u'abc'), (2, u'def')]
>>> my_ids = [idx for idx, val in my_list]
>>> my_ids
[1, 2]
Au moment de l'itération, chaque tuple est décompressé et ses valeurs sont définies sur les variables idx
et val
.
>>> x = (1, u'abc')
>>> idx, val = x
>>> idx
1
>>> val
u'abc'
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]
_
L'instruction itemgetter
renvoie une fonction qui renvoie l'index de l'élément 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')]
_
Du point de vue de la performance, en python3.X
[i[0] for i in a]
et list(Zip(*a))[0]
sont équivalentslist(map(operator.itemgetter(0), a))
Code
import timeit
iterations = 100000
init_time = timeit.timeit('''a = [(i, u'abc') for i in range(1000)]''', number=iterations)/iterations
print(timeit.timeit('''a = [(i, u'abc') for i in range(1000)]\nb = [i[0] for i in a]''', number=iterations)/iterations - init_time)
print(timeit.timeit('''a = [(i, u'abc') for i in range(1000)]\nb = list(Zip(*a))[0]''', number=iterations)/iterations - init_time)
sortie
3.491014136001468e-05
3.422205176000717e-05
si les n-uplets sont uniques, cela peut fonctionner
>>> a = [(1, u'abc'), (2, u'def')]
>>> a
[(1, u'abc'), (2, u'def')]
>>> dict(a).keys()
[1, 2]
>>> dict(a).values()
[u'abc', u'def']
>>>
quand j'ai couru (comme suggéré ci-dessus):
>>> a = [(1, u'abc'), (2, u'def')]
>>> import operator
>>> b = map(operator.itemgetter(0), a)
>>> b
au lieu de retourner:
[1, 2]
J'ai reçu ceci comme le retour:
<map at 0xb387eb8>
J'ai trouvé que je devais utiliser list ():
>>> b = list(map(operator.itemgetter(0), a))
retourner avec succès une liste en utilisant cette suggestion. Cela dit, je suis content de cette solution, merci. (testé/exécuté avec Spyder, console iPython, Python v3.6)
Ce sont des tuples, pas des ensembles. Tu peux le faire:
l1 = [(1, u'abc'), (2, u'def')]
l2 = [(tup[0],) for tup in l1]
l2
>>> [(1,), (2,)]