Extraire des éléments de la liste à des positions impaires


100

Je veux donc créer une liste qui est une sous-liste d'une liste existante.

Par exemple,

L = [1, 2, 3, 4, 5, 6, 7], Je veux créer une sous - liste litelle que licontient tous les éléments Laux positions impaires.

Bien que je puisse le faire en

L = [1, 2, 3, 4, 5, 6, 7]
li = []
count = 0
for i in L:
    if count % 2 == 1:
        li.append(i)
    count += 1

Mais je veux savoir s'il existe une autre façon de faire la même chose efficacement et en moins d'étapes.


@WaleedKhan: Pourquoi a-t-il besoin de lister les compréhensions dans une question?
Tamara Wijsman

1
@TomWijsman: Compréhensions de listes . ETA: Ne tenez pas compte de cela: j'ai cherché et découvert votre réponse qui indique que vous plaisantez. Mettez un visage souriant la prochaine fois!
David Robinson

2
@DavidRobinson: Mais d'autres personnes peuvent-elles dire cela, il n'est peut-être pas clair de comprendre ce qu'il veut dire avec deux mots ambigus. Juste poignarder ici et là avec quelques commentaires, pour que les gens se préparent et rédigent un meilleur contenu; et pour éviter de laisser le PO ou les visiteurs désemparés ... :)
Tamara Wijsman

Réponses:


229

Solution

Oui, vous pouvez:

l = L[1::2]

Et c'est tout. Le résultat contiendra les éléments placés sur les positions suivantes ( 0-basées, donc le premier élément est à la position 0, le second à 1etc.):

1, 3, 5

donc le résultat (nombres réels) sera:

2, 4, 6

Explication

Le [1::2]à la fin est juste une notation pour le découpage de liste. Il se présente généralement sous la forme suivante:

some_list[start:stop:step]

Si nous omettons start, la valeur par défaut ( 0) serait utilisée. Donc le premier élément (en position 0, car les index sont0 basés sur) serait sélectionné. Dans ce cas, le deuxième élément sera sélectionné.

Étant donné que le deuxième élément est omis, la valeur par défaut est utilisée (la fin de la liste). La liste est donc itérée du deuxième élément à la fin .

Nous avons également fourni un troisième argument ( step) qui est2 . Ce qui signifie qu'un élément sera sélectionné, le suivant sera ignoré, et ainsi de suite ...

Donc, pour résumer, dans ce cas [1::2]signifie:

  1. prenez le deuxième élément (qui, au fait, est un élément étrange, si vous en jugez à partir de l'index),
  2. sauter un élément (parce que nous en avons step=2, donc nous en sautons un, contrairement à step=1ce qui est par défaut),
  3. prenez l'élément suivant,
  4. Répétez les étapes 2 à 3. jusqu'à ce que la fin de la liste soit atteinte,

EDIT : @PreetKukreti a donné un lien pour une autre explication sur la notation de découpage de liste de Python. Voir ici: expliquer la notation de tranche de Python

Extras - remplacement du compteur par enumerate()

Dans votre code, vous créez et augmentez explicitement le compteur. En Python, ce n'est pas nécessaire, car vous pouvez énumérer à travers certains itérables en utilisant enumerate():

for count, i in enumerate(L):
    if count % 2 == 1:
        l.append(i)

Ce qui précède sert exactement le même objectif que le code que vous utilisiez:

count = 0
for i in L:
    if count % 2 == 1:
        l.append(i)
    count += 1

En savoir plus sur l'émulation de forboucles avec compteur en Python: Accéder à l'index en Python pour les boucles 'for'


@TomWijsman regarde cette question pour comprendre la syntaxe de découpage en python
Preet Kukreti

La question demande des positions impaires. Cela donne même des positions (0,2,4,6); cela ressemble à OP veut des indices (1,3,5), qui seraient donnés par [1,2,3,4,5,6,7][1::2].
Marcin

@Marcin: Oui, je suis en fait sorti avec la même conclusion (voir correction). Cela est sorti après avoir lu attentivement le code de l'OP. Le problème a résulté sur une base différente pour l'indexation (pour moi, l' élément " impair " signifiait le premier élément, pour OP apparemment c'était le deuxième , donc indexé 1).
Tadeck

1
@TomWijsman: Je suis désolé, je n'ai pas remarqué ce que vous avez changé. En effet, il existe un lien, mais il mène au projet Numarray, pas au listdécoupage de Python . Cela diffère un peu, surtout parce que la listtranche de s ne garde pas la référence à la liste d'origine (dans Numarray, vous devez appeler explicitement .copy()pour avoir quelque chose qui ne fait pas référence au tableau d'origine). Mais c'est bien d'avoir quelque chose qui peut être mieux pour certains lecteurs. Pourriez-vous poser ce lien dans le commentaire, afin que je puisse voter pour lui et il apparaîtra juste en dessous de la réponse?
Tadeck

@Tadeck "Indices impairs" signifie assez naturellement des indices qui sont des nombres impairs.
Marcin

12

Pour les positions impaires , vous voudrez probablement:

>>>> list_ = list(range(10))
>>>> print list_[1::2]
[1, 3, 5, 7, 9]
>>>>

3

J'aime les compréhensions de listes en raison de leur syntaxe Math (Set). Alors que diriez-vous de ceci:

L = [1, 2, 3, 4, 5, 6, 7]
odd_numbers = [y for x,y in enumerate(L) if x%2 != 0]
even_numbers = [y for x,y in enumerate(L) if x%2 == 0]

En gros, si vous énumérez sur une liste, vous obtiendrez l'index xet la valeur y. Ce que je fais ici, c'est mettre la valeur ydans la liste de sortie (paire ou impaire) et utiliser l'index xpour savoir si ce point est impair ( x%2 != 0).


1
Ne devrait-il pas être enumerate (L) au lieu d'énumerate (items)?
ab123

0

Vous pouvez utiliser l'opérateur AND au niveau du bit &. Voyons ci-dessous:

x = [1, 2, 3, 4, 5, 6, 7]
y = [i for i in x if i&1]
>>> 
[1, 3, 5, 7]

L'opérateur ET au niveau du bit est utilisé avec 1, et la raison pour laquelle il fonctionne parce que, un nombre impair lorsqu'il est écrit en binaire doit avoir son premier chiffre comme 1. Vérifions

23 = 1 * (2**4) + 0 * (2**3) + 1 * (2**2) + 1 * (2**1) + 1 * (2**0) = 10111
14 = 1 * (2**3) + 1 * (2**2) + 1 * (2**1) + 0 * (2**0) = 1110

ET l'opération avec 1 ne retournera que 1 (1 en binaire aura aussi le dernier chiffre 1), ssi la valeur est impaire.

Consultez la page Python Bitwise Operator pour en savoir plus.

PS: Vous pouvez utiliser tactiquement cette méthode si vous souhaitez sélectionner des colonnes paires et impaires dans un dataframe. Disons que les coordonnées x et y des points clés faciaux sont données sous forme de colonnes x1, y1, x2, etc ... Pour normaliser les coordonnées x et y avec les valeurs de largeur et de hauteur de chaque image, vous pouvez simplement effectuer

for i in range(df.shape[1]):
    if i&1:
        df.iloc[:, i] /= heights
    else:
        df.iloc[:, i] /= widths

Ce n'est pas exactement lié à la question, mais pour les scientifiques des données et les ingénieurs en vision par ordinateur, cette méthode pourrait être utile.

À votre santé!


-1

liste_ = liste (plage (9)) impression (liste_ [1 :: 2])


Veuillez répondre avec une brève explication et mettre des blocs de code correctement formatés. Merci
venkata krishnan
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.