Domanda Python ha un operatore condizionale ternario?


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


4425


origine


risposte:


Si lo era aggiunto  nella versione 2.5.
La sintassi è:

a if condition else b

Primo condition viene valutato, quindi entrambi a o b viene restituito in base al booleano  valore di condition
Se condition valuta a Vero   a viene restituito, altrimenti b viene restituito.

Per esempio:

>>> 'true' if True else 'false'
'true'
>>> 'true' if False else 'false'
'false'

Si noti che i condizionali sono un espressione , non a dichiarazione . Ciò significa che non è possibile utilizzare assegnazioni o pass o altre dichiarazioni in un condizionale:

>>> pass if False else x = 3
  File "<stdin>", line 1
    pass if False else x = 3
          ^
SyntaxError: invalid syntax

In tal caso, devi usare un normale if affermazione invece di un condizionale.


Tieni presente che è sfigurato da alcuni Pythonistas per diversi motivi:

  • L'ordine degli argomenti è diverso da molti altri linguaggi (come C, Ruby, Java, ecc.), Che possono portare a bug quando le persone che non hanno familiarità con il comportamento "sorprendente" di Python lo usano (potrebbero invertire l'ordine).
  • Alcuni lo trovano "ingombrante", poiché va contro il normale flusso del pensiero (pensando prima alla condizione e poi agli effetti).
  • Ragioni stilistiche

Se hai difficoltà a ricordare l'ordine, ricorda che se lo leggi ad alta voce, dici (quasi) cosa intendi. Per esempio, x = 4 if b > 8 else 9 viene letto ad alta voce come x will be 4 if b is greater than 8 otherwise 9.

Documentazione ufficiale:


5283



Puoi indicizzare in una tupla:

(falseValue, trueValue)[test]

test ha bisogno di tornare Vero  o falso .
Potrebbe essere più sicuro implementarlo sempre come:

(falseValue, trueValue)[test == True]

oppure puoi usare il built-in bool() per assicurare a booleano  valore:

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

591



Per le versioni precedenti alla 2.5, c'è il trucco:

[expression] and [on_true] or [on_false]

Può dare risultati sbagliati quando on_true   ha un falso valore booleano. 1
Anche se ha il vantaggio di valutare le espressioni da sinistra a destra, il che è più chiaro a mio avviso.

1. Esiste un equivalente di C "?:" Operatore ternario?


245



espressione1  Se condizione  altro espressione2

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

154



A partire dal la documentazione :

Le espressioni condizionali (a volte chiamate "operatori ternari") hanno la priorità più bassa di tutte le operazioni Python.

L'espressione x if C else y prima valuta la condizione, C  ( non x ); Se C  è vero, X  viene valutato e viene restituito il suo valore; altrimenti, y  viene valutato e viene restituito il suo valore.

Vedere PEP 308  per maggiori dettagli sulle espressioni condizionali.

Novità dalla versione 2.5.


105



Un operatore per un'espressione condizionale in Python è stato aggiunto nel 2006 come parte di Proposta di miglioramento Python 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 sono gli operandi pigramente valutato .

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 metodo (meno affidabile), ma più semplice da usare and e or operatori:

result = (a > b) and x or y

tuttavia questo non funzionerà se x sarebbe False.

Una soluzione possibile è fare x e y liste o tuple come di seguito:

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 trarne vantaggio get(key, default), per esempio:

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

Fonte: ?: in Python su Wikipedia


78



@su:

Sfortunatamente, il

(falseValue, trueValue)[test]

la soluzione non ha un comportamento di cortocircuito; quindi sia falseValue che trueValue vengono valutati indipendentemente dalla condizione. Questo potrebbe essere subottimale o addirittura infestato (vale a dire sia trueValue che falseValue potrebbero essere metodi e avere effetti collaterali).

Una soluzione a questo sarebbe

(lambda: falseValue, lambda: trueValue)[test]()

(l'esecuzione è ritardata fino a quando il vincitore non è noto;)), ma introduce un'incoerenza tra oggetti chiamabili e non richiamabili. Inoltre, non risolve il caso quando si utilizzano le proprietà.

E così la trama va - scegliere tra 3 soluzioni menzionate è un compromesso tra avere la caratteristica di cortocircuito, usare almeno python 2.5 (IMHO non è più un problema) e non essere incline a "trueValue-evaluation-to-false" errori.


72



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, c'è un potenziale problema, che se cond valuta a True e on_true valuta a False poi on_false viene restituito al posto di 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.


48