OVH Cloud OVH Cloud

Equivalent du (a ? b : c) du C ?

17 réponses
Avatar
Nicolas Pourcelot
Bonjour,
je voudrais remplacer le (a ? b : c) du C par un équivalent python.
Je sais qu'en général on peut le faire avec ( a and b or c), mais ça
pose problème si b peut s'annuler.
Il me semble qu'il y a une astuce, mais je ne m'en rappelle plus ;-)
Merci d'avance !

Nicolas

7 réponses

1 2
Avatar
DjPython
Salut
voila une petite fonction

def iif(exp,val1,val2):
vReturn = exp and [val1] or [val2]
return vReturn[0]

DjPython
Avatar
F. Petitjean
Salut
voila une petite fonction

def iif(exp,val1,val2):
vReturn = exp and [val1] or [val2]
return vReturn[0]

DjPython


Merci, mais ce nom « iif » et l'absence de __doc__ « m'interpelle «.
Le fait de ne pas avoir un nom bien (re)connu ne serait-il pas dû à
l'absence de sa nécessité (impérieuse, et là je pars car je sens que
c'est de la philosophie à deux francs.

Question: pour appeler iif() il faut donner trois arguments, quand se
fait l'évaluation des arguments ?

--
rien n'est simple. Tout se complique
Le petit Nicolas par Sempé.

Avatar
tiissa
F. Petitjean wrote:
Question: pour appeler iif() il faut donner trois arguments, quand se
fait l'évaluation des arguments ?


C'est une question rhétorique ?
Sinon je répondrais : comme pour toute fonction, lors de son appel.

def f():
... print 'a'



... return 2
...
def g(a):
... return 0



...
g(f())
a



0







Avatar
F. Petitjean
F. Petitjean wrote:
Question: pour appeler iif() il faut donner trois arguments, quand se
fait l'évaluation des arguments ?


C'est une question rhétorique ?


« rhétorique » je ne sais pas, mais c'est une question.

Sinon je répondrais : comme pour toute fonction, lors de son appel.


ok. Je suppose qu'il faut comprendre que ce sont tous les arguments qui
sont évalués lors de l'appel. Dans ce cas toute la logique de
court-circuitage du cond ? var1 : var2 du C est perdue, et la fonction
iif() n'est plus cotée sur le maché impitoyable des développeurs Python
:-).

Question subsidiaire :
Quand les paramètres de la fonction zarbi :
def zarbi(a, b=None, *args, **kwargs):
sont-ils définis ?

--
Tout se complique
Sempé (met en scène le petit Nicolas)


Avatar
tiissa
F. Petitjean wrote:
C'est une question rhétorique ?


« rhétorique » je ne sais pas, mais c'est une question.


Je pensais que vous connaissiez la réponse, auquel cas la forme
interrogative aurait été un simple procédé de discours.


ok. Je suppose qu'il faut comprendre que ce sont tous les arguments qui
sont évalués lors de l'appel


En effet, mon exemple n'était pas assez explicite ?


Dans ce cas toute la logique de
court-circuitage du cond ? var1 : var2 du C est perdue, et la fonction
iif() n'est plus cotée sur le maché impitoyable des développeurs Python
:-).


Un de ses intérêts pour certains serait encore sa concision (/one-liner/).

Question subsidiaire :
Quand les paramètres de la fonction zarbi :
def zarbi(a, b=None, *args, **kwargs):
sont-ils définis ?


b est initialisé lors de la déclaration de la fonction :

a=0
def f(b=a):
... return b



...
f(3)
3



f()
0



a=1
f()
0




Les autres sont évalués lors de l'appel de la fonction, il me semble.

--
Tout se complique
Sempé (met en scène le petit Nicolas)


Pour information, le délimiteur de signature le plus couramment reconnu
(et admis) est '-- '.



Avatar
Jean-Baptiste
Je propose cette solution :

{True:b,False:c}[a]

je trouve ça 'assez' lisible.
Avatar
tiissa
Jean-Baptiste wrote:
{True:b,False:c}[a]

je trouve ça 'assez' lisible.


C'est en effet un peu plus clair (mais plus long) que la version (c,b)[a].
Mais ça en a tous les autres défauts.

En particulier, contrairement à la version C ou and-or, l'expression a
doit être un booléen (ou 0 ou 1) et les expressions b et c seront toutes
les deux évaluées quelque soit sa valeur de vérité.


l=[6,4]
{True: 3, False: 5}[len(l)]
Traceback (most recent call last):



File "<stdin>", line 1, in ?
KeyError: 2
{True: 3, False: 5}[()]
Traceback (most recent call last):



File "<stdin>", line 1, in ?
KeyError
def f():
... print 'f'



... return 4
...
{True: f(), False: 5}[False]
f



5
() and f() or 5
5










1 2