web-dev-qa-db-fra.com

Est-il possible d'utiliser 'else' dans une compréhension de liste?

Voici le code que je tentais de transformer en compréhension de liste:

table = ''
for index in xrange(256):
    if index in ords_to_keep:
        table += chr(index)
    else:
        table += replace_with

Y a-t-il un moyen d'ajouter l'énoncé else à cette compréhension?

table = ''.join(chr(index) for index in xrange(15) if index in ords_to_keep)
182
Josh

La syntaxe a if b else c est un opérateur ternaire dans Python qui donne a si la condition b est vraie. Sinon, il est évalué à c. Il peut être utilisé dans les énoncés de compréhension:

>>> [a if a else 2 for a in [0,1,0,3]]
[2, 1, 2, 3]

Donc, pour votre exemple,

table = ''.join(chr(index) if index in ords_to_keep else replace_with
                for index in xrange(15))
295
Amber

Si vous voulez un else que vous ne voulez pas filtrer la compréhension de la liste, vous voulez qu'il répète chaque valeur. Vous pouvez utiliser true-value if cond else false-value comme instruction à la place, et retirez le filtre de la fin:

table = ''.join(chr(index) if index in ords_to_keep else replace_with for index in xrange(15))
15
Michael Mrozek

Pour utiliser le else dans les interprétations de liste dans python, vous pouvez essayer l'extrait de code ci-dessous. Cela résoudrait votre problème, l'extrait de code est testé sur python 2.7 et python 3.5.

obj = ["Even" if i%2==0 else "Odd" for i in range(10)]
8
Chitrank Dixit

Oui , else peut être utilisé dans Python dans un listcompréhension avec un expression conditionnelle ("opérateur ternaire"):

>>> [("A" if b=="e" else "c") for b in "comprehension"]
['c', 'c', 'c', 'c', 'c', 'A', 'c', 'A', 'c', 'c', 'c', 'c', 'c']

Ici, les parenthèses "()" ne sont que pour souligner l'expression conditionnelle, elles ne sont pas forcément requises ( Priorité de l'opérateur ).

De plus, plusieurs expressions peuvent être imbriquées, ce qui donne plus de elses et du code plus difficile à lire:

>>> ["A" if b=="e" else "d" if True else "x" for b in "comprehension"]
['d', 'd', 'd', 'd', 'd', 'A', 'd', 'A', 'd', 'd', 'd', 'd', 'd']
>>>

Sur une note connexe, une compréhension peut également contenir sa propre condition if à la fin:

>>> ["A" if b=="e" else "c" for b in "comprehension" if False]
[]
>>> ["A" if b=="e" else "c" for b in "comprehension" if "comprehension".index(b)%2]
['c', 'c', 'A', 'A', 'c', 'c']

Condition s ? Oui, plusieurs ifs sont possibles, et en réalité plusieurs fors:

>>> [i for i in range(3) for _ in range(3)]
[0, 0, 0, 1, 1, 1, 2, 2, 2]
>>> [i for i in range(3) if i for _ in range(3) if _ if True if True]
[1, 1, 2, 2]

(Le soulignement simple _ est un nom de variable valide ( identifiant ) en Python, utilisé ici uniquement pour indiquer que c'est pas réellement utilisé. Il a un signification spéciale en mode interactif )

Utiliser ceci pour une expression conditionnelle supplémentaire est possible, mais sans réelle utilité:

>>> [i for i in range(3)]
[0, 1, 2]
>>> [i for i in range(3) if i]
[1, 2]
>>> [i for i in range(3) if (True if i else False)]
[1, 2]

Les interprétations peuvent également être imbriquées pour créer des listes "multidimensionnelles" ("matrices"):

>>> [[i for j in range(i)] for i in range(3)]
[[], [1], [2, 2]]

Enfin et surtout, une compréhension ne se limite pas à créer un list, c'est-à-dire que else et if peuvent également être utilisés de la même manière dans un set compréhension:

>>> {i for i in "set comprehension"}
{'o', 'p', 'm', 'n', 'c', 'r', 'i', 't', 'h', 'e', 's', ' '}

et a dictionary compréhension:

>>> {k:v for k,v in [("key","value"), ("dict","comprehension")]}
{'key': 'value', 'dict': 'comprehension'}

La même syntaxe est également utilisée pour Expressions du générateur :

>>> for g in ("a" if b else "c" for b in "generator"):
...     print(g, end="")
...
aaaaaaaaa>>>

qui peut être utilisé pour créer un Tuple ( il n'y a pas de compréhension de Tuple ).


6
handle

Excellentes réponses, mais je voulais juste mentionner que le mot clé "pass" ne fonctionnera pas dans la partie if/else de la liste-comprehension (comme indiqué dans les exemples mentionnés ci-dessus).

#works
list1 = [10, 20, 30, 40, 50]
newlist2 = [x if x > 30 else x**2 for x in list1 ]
print(newlist2, type(newlist2))

#but this WONT work
list1 = [10, 20, 30, 40, 50]
newlist2 = [x if x > 30 else pass for x in list1 ]
print(newlist2, type(newlist2))

Ceci est essayé et testé sur python 3.4. Erreur est comme ci-dessous:

newlist2 = [x if x > 30 else pass for x in list1 ]                                    
SyntaxError: invalid syntax

Donc, essayez d'éviter les pass-es dans les compréhensions de liste

2
Plankton

Aussi, aurais-je raison de conclure que la compréhension par liste est le moyen le plus efficace de procéder?

Peut être. Les compréhensions de liste ne sont pas intrinsèquement efficaces sur le plan informatique. Il fonctionne toujours en temps linéaire.

D'après mon expérience personnelle: j'ai considérablement réduit le temps de calcul lorsque je traite de grands ensembles de données en remplaçant les interprétations de liste (celles qui sont imbriquées) par des structures de type pour les boucles pour les ajouts de liste/boucle que vous avez ci-dessus. Dans cette application, je doute que vous remarquiez une différence.

1
Donald Miner