Outils pour utilisateurs

Outils du site


if-then-else_monoligne

Un "if-then-else" monoligne utilisable dans une expression et dans une fonction lambda

Problématique

le “if”, nécessaire pour restituer un résultat différent selon une condition, est une instruction et, en tant que tel, n'est pas permis dans une expression ni dans une fonction lambda.

Il s'agit en fait de simuler ce qui existe dans certains langages comme (cond ? si_oui : si_non)

Solution avant la version 2.5 de Python

Prenons d'abord une solution simple:

(cond and x or y)

Et prenons un exemple:

x=2
y=3
print (x<y and x or y)  # affiche 2
print (x>y and x or y)  # affiche 3

le “and” sera exécuté avant le “or”.

Par ailleurs, si (cond and x) vaut True, le “or” ne sera jamais exécuté.

donc, si cond est vrai ainsi que x, renvoi de x. Sinon, le or est exécuté et y est renvoyé.

Cela semble bien fonctionner, mais dans cette forme simplifiée, si x=0, ça ne marche plus:

x=0
y=3
print (x<y and x or y)  # affiche 3 au lieu de 0

En effet, pour que ça marche, il ne faut pas que x puisse être évalué à False (donc ni à 0, ni à “”, ni à [], ni à (), ni à {}).

On utilise une astuce: une liste qui, si elle n'est pas vide, sera toujours True (essayez: même [False] est évalué à True!).

La solution est donc:

(cond and [x] or [y])[0]

qui donne le même résultat que:

if cond:
    renvoi de x
else:
    renvoi de y

Exemple:

x=0
y=3
print (x<y and [x] or [y])[0]  # affiche 0
print (x>y and [x] or [y])[0]  # affiche 3

Et, effectivement, cette forme astucieuse peut être utilisée dans une fonction lambda alors qu'un if serait interdit:

est_pair = lambda x: ((x%2==0) and ['oui'] or ['non'])[0]
print est_pair(10)  # affiche 'oui'
print est_pair(11)  # affiche 'non'

Dans cet exemple, on pourrait éviter l'utilisation de la liste, mais n'oubliez pas: une chaîne vide est évaluée à False!

Solution intégrée dans la version 2.5 de Python

Avec Python 2.5, on a enfin un “if then else monoligne”, même s'il n'est pas facile à trouver dans le manuel.

La syntaxe retenue est:

(x if cond else y)

Exemple:

x=0
y=3
print (x if x<y else y)  # affiche 0
print (x if x>y else y)  # affiche 3

Cette solution est également utilisable dans une fonction lambda alors qu'un “if” serait interdit:

toto = lambda x,y: (x if x<y else y)
toto(2,3)  # affiche: 2
toto(2,1)  # affiche: 1

Voir aussi la pep 308: http://www.python.org/dev/peps/pep-0308/

if-then-else_monoligne.txt · Dernière modification: 2008/06/15 07:04 par tyrtamos

Outils de la page