web-dev-qa-db-fra.com

Python pour et si sur une seule ligne

J'ai un problème avec python.

Je fais une liste simple:

>>> my_list = ["one","two","three"]

Je veux créer un "code à une seule ligne" pour trouver une chaîne.

par exemple, j'ai ce code:

>>> [(i) for i in my_list if i=="two"]
['two']

Mais quand je regarde la variable est fausse (je trouve la dernière valeur de ma liste):

>>> print i
three

Pourquoi ma variable contient-elle le dernier élément et non l'élément que je souhaite trouver?

8
rostonik

Vous produisez une liste filtrée en utilisant une liste de compréhension. i est toujours lié à chacun des éléments de cette liste et le dernier élément est toujours 'three', même s'il a été filtré ultérieurement de la liste en cours de production.

Vous ne devriez pas utiliser une liste de compréhension pour choisir un élément. Utilisez simplement une boucle for et break pour la terminer:

for elem in my_list:
    if elem == 'two':
        break

Si vous devez avoir une ligne (ce qui serait contraire à la philosophie de Python, où la lisibilité compte), utilisez la fonction next() et une expression génératrice:

i = next((elem for elem in my_list if elem == 'two'), None)

qui définira i à None s’il n’existe pas d’élément correspondant.

Ce qui précède n’est pas un filtre utile; vous testez essentiellement si la valeur 'two' est dans la liste. Vous pouvez utiliser in pour cela:

elem = 'two' if 'two' in my_list else None
13
Martijn Pieters

Quand vous effectuez

>>> [(i) for i in my_list if i=="two"]

i est itéré dans la liste my_list. Lorsque la compréhension de la liste termine l'évaluation, i est affecté au dernier élément de l'itération, qui est "three".

10
Cong Ma

Dans la compréhension de liste, la variable de boucle i devient globale. Après l'itération dans la boucle for, il s'agit d'une référence au dernier élément de votre liste.

Si vous voulez toutes les correspondances, assignez la liste à une variable:

filtered =  [ i for i in my_list if i=='two']

Si vous ne voulez que le premier match, vous pouvez utiliser un générateur de fonctions

try:
     m = next( i for i in my_list if i=='two' )
except StopIteration:
     m = None
1
desiato