`elif` dans les conditions de compréhension de liste


129

Pouvons-nous utiliser elifdans la compréhension de liste?

Exemple :

l = [1, 2, 3, 4, 5]

for values in l:
    if values==1:
        print 'yes'
    elif values==2:
        print 'no'
    else:
        print 'idle'

Pouvons-nous inclure la elifcompréhension de la liste dans notre liste, d'une manière similaire au code ci-dessus?

Par exemple, une réponse comme:

['yes', 'no', 'idle', 'idle', 'idle']

Jusqu'à présent, je n'ai utilisé ifet elseen compréhension de liste.

Réponses:


250

Les expressions conditionnelles de Python ont été conçues exactement pour ce type de cas d'utilisation:

>>> l = [1, 2, 3, 4, 5]
>>> ['yes' if v == 1 else 'no' if v == 2 else 'idle' for v in l]
['yes', 'no', 'idle', 'idle', 'idle']

J'espère que cela t'aides :-)


5
Il y a une histoire intéressante dans la syntaxe. Pendant de nombreuses années avant leur introduction, les "expressions tertiaires" ont été l'un des cinq changements les plus demandés dans la langue. Puisque Guido van Rossum l'a explicitement conçu comme un langage basé sur des déclarations, il a fermement résisté pendant longtemps (les expressions tertiaires, et en particulier leur abus, sont des sources de beaucoup d'obscurité dans le code). Lorsqu'il a finalement succombé, il a annoncé qu'il avait délibérément choisi une syntaxe qui décourageait la surutilisation. Comme d'habitude, il a néanmoins fait un travail de design élégant.
holdenweb

1
Ternaire, bon sang (il écrivit, remarquant son erreur dyslexique trop tard pour être édité).
holdenweb

2
Pendant que je vote pour cette réponse, je tiens à mentionner ceci: pour 1 paire de if / else est facile à lire, 2 paires: c'est de plus en plus difficile à comprendre. Ne mentionnez même pas 3 paires. Si l'expression nécessite 3 paires ou plus, un dictionnaire ou une fonction distincte rendra les choses plus faciles à lire et à comprendre.
Hai Vu le

1
Je voudrais ajouter non pas une solution à ce problème, mais un rappel de code propre: puisque cette compréhension de liste a trois conditions, elle pourrait probablement être refactorisée en une méthode plus descriptive. Mon point est le suivant: martinfowler.com/bliki/FunctionLength.html :)
Alvaro Cavalcanti

Je suis tombé sur un cas où j'avais besoin d'un elif, mais seulement deux valeurs. En utilisant cet exemple, j'aurais juste eu besoin ['yes', 'no']d'être fait. Pour ce faire, vous pouvez faire: ['yes' if v == 1 else 'no' for v in l if values in [1,2]]. Je ne peux actuellement pas penser à un moyen plus propre de le faire.
dTanMan

48
>>> d = {1: 'yes', 2: 'no'}
>>> [d.get(x, 'idle') for x in l]
['yes', 'no', 'idle', 'idle', 'idle']

4
Je pense que ce formulaire est beaucoup plus facile à digérer que d'essayer de faire une logique if / else vraiment longue et compliquée dans la liste comp
jdi

5
@jdi Bien que les expressions conditionnelles ne soient pas à votre goût, elles ont été spécifiquement conçues pour gérer les chaînes if-elif-elif-else, tout comme l'OP l'a demandé. Ils ne sont pas difficiles à apprendre et peut gérer grâce des situations qui ne sont pas aussi prête à la logique de recherche dans le dictionnaire: 'A' if grade>=90 else 'B' if grade>=80 else 'C' if grade>=70 else 'F'.
Raymond Hettinger

1
Y a-t-il un avantage à définir en ddehors de la compréhension?
Chris_Rands

La raison pour laquelle j'aime mieux la compréhension de la liste est qu'elle se lit comme l'anglais. Même un non-programmeur pourrait comprendre ce qu'il fait. Avec cette solution, vous devez comprendre la méthode dict.get ().
Tim Skov Jacobsen

26

Vous pouvez, en quelque sorte.

Notez que lorsque vous utilisez une syntaxe comme:

['yes' if v == 1 else 'no' for v in l]

Vous utilisez la forme ternaire de l'opérateur if / else (si vous êtes familier avec des langages comme C, c'est comme la ?:construction:) (v == 1 ? 'yes' : 'no').

La forme ternaire de l'opérateur if / else n'a pas de 'elif' intégré, mais vous pouvez le simuler dans la condition 'else':

['yes' if v == 1 else 'no' if v == 2 else 'idle' for v in l]

C'est comme dire:

for v in l:
    if v == 1 :
        print 'yes'
    else:
        if v == 2:
            print 'no'
        else:
            print 'idle'

Il n'y a donc pas de construction 'elif' directe comme vous l'avez demandé, mais elle peut être simulée avec des instructions if / else imbriquées.


1
Le dernier code de paragraphe est très perspicace merci!
devianceee

3

Peut-être que vous voulez ceci:

l = [1, 2, 3, 4, 5] 

print ([['idle','no','yes'][2*(n==1)+(n==2)] for n in l])

2

Vous pouvez utiliser la compréhension de liste si vous allez créer une autre liste à partir de l'original.

>>> l = [1, 2, 3, 4, 5]
>>> result_map = {1: 'yes', 2: 'no'}
>>> [result_map[x] if x in result_map else 'idle' for x in l]
['yes', 'no', 'idle', 'idle', 'idle']

2

Un autre moyen simple consiste à utiliser la compréhension de liste conditionnelle comme ceci:

l=[1,2,3,4,5]
print [[["no","yes"][v==1],"idle"][v!=1 and v!=2] for v in l]

vous donne la bonne réponse:

['oui', 'non', 'inactif', 'inactif', 'inactif']

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.