web-dev-qa-db-fra.com

Extrait le premier élément de chaque sous-liste

Je me demande quel est le meilleur moyen d'extraire le premier élément de chaque sous-liste d'une liste de listes et de l'ajouter à une nouvelle liste. Donc si j'ai:

lst = [[a,b,c], [1,2,3], [x,y,z]]

et je veux extraire a, 1 et x et créer une liste distincte de ceux-ci.

J'ai essayé:

lst2.append(x[0] for x in lst)
120
konrad

Utilisation de compréhension de la liste :

>>> lst = [['a','b','c'], [1,2,3], ['x','y','z']]
>>> lst2 = [item[0] for item in lst]
>>> lst2
['a', 1, 'x']
165
alecxe

Vous pouvez utiliser Zip:

>>> lst=[[1,2,3],[11,12,13],[21,22,23]]
>>> Zip(*lst)[0]
(1, 11, 21)

Ou bien, Python 3 où Zip ne produit pas de liste:

>>> list(Zip(*lst))[0]
(1, 11, 21)

Ou,

>>> next(Zip(*lst))
(1, 11, 21)

Ou, (mon préféré) utilisez numpy:

>>> import numpy as np
>>> a=np.array([[1,2,3],[11,12,13],[21,22,23]])
>>> a
array([[ 1,  2,  3],
       [11, 12, 13],
       [21, 22, 23]])
>>> a[:,0]
array([ 1, 11, 21])
70
dawg

Python inclut une fonction appelée itemgetter pour renvoyer l'élément à un index spécifique dans une liste:

from operator import itemgetter

Passez la fonction itemgetter () à l'index de l'élément que vous souhaitez récupérer. Pour récupérer le premier élément, vous utiliseriez itemgetter (0). La chose importante à comprendre est que itemgetter (0) renvoie lui-même une fonction. Si vous passez une liste à cette fonction, vous obtenez l'élément spécifique:

itemgetter(0)([10, 20, 30]) # Returns 10

Ceci est utile lorsque vous le combinez avec map (), qui prend une fonction comme premier argument et une liste (ou tout autre élément itérable) comme second argument. Il retourne le résultat de l'appel de la fonction sur chaque objet dans l'itérable:

my_list = [['a', 'b', 'c'], [1, 2, 3], ['x', 'y', 'z']]
list(map(itemgetter(0), my_list)) # Returns ['a', 1, 'x']

Notez que map () renvoie un générateur, ainsi le résultat est transmis à list () pour obtenir une liste réelle. En résumé, votre tâche pourrait se faire comme ceci:

lst2.append(list(map(itemgetter(0), lst)))

Il s'agit d'une méthode alternative à l'utilisation d'une compréhension de liste et la méthode à choisir dépend fortement du contexte, de la lisibilité et des préférences.

Plus d'infos: https://docs.python.org/3/library/operator.html#operator.itemgetter

13
Christian Abbott

Avait le même problème et est devenu curieux de la performance de chaque solution.

Voici le %timeit:

import numpy as np
lst = [['a','b','c'], [1,2,3], ['x','y','z']]

Le premier numpy-way, transformant le tableau:

%timeit list(np.array(lst).T[0])
4.9 µs ± 163 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

Entièrement natif en utilisant la compréhension de liste (comme expliqué par @alecxe):

%timeit [item[0] for item in lst]
379 ns ± 23.1 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

Une autre manière native en utilisant Zip (comme expliqué par @dawg):

%timeit list(Zip(*lst))[0]
585 ns ± 7.26 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

Deuxième numpy-way. Également expliqué par @dawg:

%timeit list(np.array(lst)[:,0])
4.95 µs ± 179 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

Étonnamment (enfin, du moins pour moi), la méthode native utilisant la compréhension par liste est la plus rapide et environ 10 fois plus rapide que la méthode numpy. Exécuter les deux voies numpy sans la finale list enregistre environ un µs qui est toujours dans la différence 10x.

Notez que, lorsque j'ai entouré chaque extrait de code avec un appel à len, afin de m'assurer que les générateurs fonctionnent jusqu'à la fin, la synchronisation est restée la même.

10
jboi

Votre code est presque correct. Le seul problème est l'utilisation de la compréhension de liste.

Si vous utilisez comme: (x [0] pour x dans lst), un objet générateur est renvoyé. Si vous utilisez comme: [x [0] pour x dans lst], il retourne une liste.

Lorsque vous ajoutez le résultat de la compréhension de liste à une liste, le résultat de la compréhension de liste est l'élément unique de la liste.

lst = [["a","b","c"], [1,2,3], ["x","y","z"]]
lst2 = []
lst2.append([x[0] for x in lst])
print lst2[0]

lst2 = [['a', 1, 'x']]

lst2 [0] = ['a', 1, 'x']

S'il vous plaît laissez-moi savoir si je me trompe.

2
Abhishek Mittal
lst = [['a','b','c'], [1,2,3], ['x','y','z']]
outputlist = []
for values in lst:
    outputlist.append(values[0])

print(outputlist) 

Sortie: ['a', 1, 'x']

1
PrabhuPrakash

Vous avez dit que vous avez une liste existante. Alors je vais avec ça.

>>> lst1 = [['a','b','c'], [1,2,3], ['x','y','z']]
>>> lst2 = [1, 2, 3]

En ce moment, vous ajoutez l'objet générateur à votre deuxième liste.

>>> lst2.append(item[0] for item in lst)
>>> lst2
[1, 2, 3, <generator object <genexpr> at 0xb74b3554>]

Mais vous voulez probablement que ce soit une liste de premiers éléments

>>> lst2.append([item[0] for item in lst])
>>> lst2
[1, 2, 3, ['a', 1, 'x']]

Maintenant, nous avons ajouté la liste des premiers éléments à la liste existante. Si vous souhaitez ajouter les éléments à eux-mêmes, et non une liste, aux éléments existants, utilisez list.extend. Dans ce cas, nous n'avons pas à nous préoccuper de l'ajout d'un générateur, car extend utilisera ce générateur pour ajouter chaque élément obtenu à partir de là, afin d'étendre la liste actuelle.

>>> lst2.extend(item[0] for item in lst)
>>> lst2
[1, 2, 3, 'a', 1, 'x']

ou

>>> lst2 + [x[0] for x in lst]
[1, 2, 3, 'a', 1, 'x']
>>> lst2
[1, 2, 3]

https://docs.python.org/3.4/tutorial/datastructures.html#more-on-listshttps://docs.python.org/3.4/tutorial/datastructures. html # liste-compréhensions

0
Hendrik