Python ha un operatore condizionale ternario?



Answers

Puoi indicizzare in una tupla:

(falseValue, trueValue)[test]

test deve restituire Vero o Falso .
Potrebbe essere più sicuro implementarlo sempre come:

(falseValue, trueValue)[test == True]

oppure puoi usare il built-in bool() per assicurare un valore Boolean :

(falseValue, trueValue)[bool(<expression>)]
Question

Se Python non ha un operatore condizionale ternario, è possibile simularne uno utilizzando altri costrutti linguistici?




Python ha un operatore condizionale ternario?

Sì. Dal file di grammatica :

test: or_test ['if' or_test 'else' test] | lambdef

La parte di interesse è:

or_test ['if' or_test 'else' test]

Quindi, un'operazione ternaria condizionale ha la forma:

expression1 if expression2 else expression3

expression3 sarà valutato pigramente (cioè valutato solo se expression2 è false in un contesto booleano). E a causa della definizione ricorsiva, puoi incatenarli indefinitamente (anche se potrebbe essere considerato un cattivo stile).

expression1 if expression2 else expression3 if expression4 else expression5 # and so on

Una nota sull'utilizzo:

Nota che ogni if deve essere seguito con un else . Le persone che imparano le comprensioni delle liste e le espressioni del generatore possono ritenere che questa sia una lezione difficile da imparare - il seguente non funzionerà, dato che Python si aspetta una terza espressione per un altro:

[expression1 if expression2 for element in iterable]
#                          ^-- need an else here

che solleva un SyntaxError: invalid syntax . Quindi quanto sopra è una parte di logica incompleta (forse l'utente si aspetta un no-op nella falsa condizione) o quello che può essere inteso è usare expression2 come filtro - nota che il seguente è legale Python:

[expression1 for element in iterable if expression2]

expression2 funziona come un filtro per la comprensione dell'elenco e non è un operatore condizionale ternario.

Sintassi alternativa per un caso più stretto:

Potresti trovare un po 'doloroso scrivere quanto segue:

expression1 if expression1 else expression2

expression1 dovrà essere valutato due volte con l'utilizzo di cui sopra. Può limitare la ridondanza se è semplicemente una variabile locale. Tuttavia, un idioma Pythonic comune e performante per questo caso d'uso è l'uso or il comportamento shortcutting:

expression1 or expression2

che è equivalente in semantica. Si noti che alcune guide di stile possono limitare questo utilizzo per motivi di chiarezza: esso racchiude molto significato in pochissima sintassi.




C'è un'opzione ternaria come indicato in altre risposte, ma puoi anche simularla usando "o" se stai sfidando un valore booleano o Nessuno:

>>> a = False
>>> b = 5
>>> a or b
5

>>> a = None
>>> a or b
5



In [1]: a = 1 if False else 0

In [2]: a
Out[2]: 0

In [3]: b = 1 if True else 0

In [4]: b
Out[4]: 1



Sì.

>>> b = (True if 5 > 4 else False)
>>> print b
True



Potresti trovarlo spesso

cond and on_true or on_false

ma questo porta a un problema quando on_true == 0

>>> x = 0
>>> print x == 0 and 0 or 1 
1
>>> x = 1
>>> print x == 0 and 0 or 1 
1

dove ti aspetteresti per un normale operatore ternario questo risultato

>>> x = 0
>>> print 0 if x == 0 else 1 
0
>>> x = 1
>>> print 0 if x == 0 else 1 
1



Per Python 2.5 e versioni successive esiste una sintassi specifica:

[on_true] if [cond] else [on_false]

Nei vecchi Python un operatore ternario non è implementato ma è possibile simularlo.

cond and on_true or on_false

Tuttavia, esiste un potenziale problema, che se cond valuta su True e su on_true valutato su False viene restituito on_true anziché on_true . Se vuoi questo comportamento il metodo è OK, altrimenti usa questo:

{True: on_true, False: on_false}[cond is True] # is True, not == True

che può essere avvolto da:

def q(cond, on_true, on_false)
    return {True: on_true, False: on_false}[cond is True]

e usato in questo modo:

q(cond, on_true, on_false)

È compatibile con tutte le versioni di Python.




espressione1 se condizione else espressione2

>>> a = 1
>>> b = 2
>>> 1 if a > b else -1 
-1
>>> 1 if a > b else -1 if a < b else 0
-1



Più un suggerimento che una risposta (non è necessario ripetere l'ovvio per il periodo di tempo), ma a volte lo uso come scorciatoia oneliner in tali costrutti:

if conditionX:
    print('yes')
else:
    print('nah')

, diventa:

print('yes') if conditionX else print('nah')

Alcuni (molti) potrebbero disapprovarlo come unpitonico (anche, rubino-ish :), ma personalmente lo trovo più naturale - cioè come lo si esprimerebbe normalmente, più un po 'più visivamente accattivante in grandi blocchi di codice.




Un operatore per un'espressione condizionale in Python è stato aggiunto nel 2006 come parte di Python Enhancement Proposal 308 . La sua forma differisce dal comune ?: Operatore ed è:

<expression1> if <condition> else <expression2>

che è equivalente a:

if <condition>: <expression1> else: <expression2>

Ecco un esempio:

result = x if a > b else y

Un'altra sintassi che può essere utilizzata (compatibile con le versioni precedenti alla 2.5):

result = (lambda:y, lambda:x)[a > b]()

dove gli operandi vengono pigramente valutati .

Un altro modo è indicizzare una tupla (che non è coerente con l'operatore condizionale della maggior parte delle altre lingue):

result = (y, x)[a > b]

o dizionario esplicitamente costruito:

result = {True: x, False: y}[a > b]

Un altro (meno affidabile), ma il metodo più semplice è quello di utilizzare and e or operatori:

result = (a > b) and x or y

tuttavia questo non funzionerà se x fosse False .

Una possibile soluzione è quella di creare liste e tuple x e y come nell'esempio seguente:

result = ((a > b) and [x] or [y])[0]

o:

result = ((a > b) and (x,) or (y,))[0]

Se stai lavorando con i dizionari, invece di usare un condizionale ternario, puoi usufruire di get(key, default) , ad esempio:

shell = os.environ.get('SHELL', "/bin/sh")

Fonte: ?:




Related