Una riga assegnazione if-condition


140

Ho il codice seguente

num1 = 10
someBoolValue = True

Ho bisogno di impostare il valore di num1per 20se someBoolValueè True; e non fare diversamente. Quindi, ecco il mio codice per quello

num1 = 20 if someBoolValue else num1

C'è un modo in cui potrei evitare la ...else num1parte per renderla più pulita? Un equivalente a

if someBoolValue:
    num1 = 20

Ho provato a sostituire con ...else passquesto modo: num1=20 if someBoolValue else pass. Tutto quello che ho avuto è stato un errore di sintassi. Né potrei semplicemente omettere la ...else num1parte.


2
Basta cambiare tutto in num1 = 20 if someBoolValue else 10. Quindi salvi anche la num1=10linea?
Thomas Ahle,

Grazie. Ma questo non è esattamente il mio codice. Volevo dire che num1esiste già ...
bdhar,

Risposte:


196

Non penso che sia possibile in Python, dal momento che ciò che stai effettivamente cercando di fare probabilmente si espande in qualcosa del genere:

num1 = 20 if someBoolValue else num1

Se si esclude else num1 , si riceverà un errore di sintassi poiché sono abbastanza sicuro che l'assegnazione debba effettivamente restituire qualcosa.

Come altri hanno già detto, potresti farlo, ma è un male perché probabilmente finirai per confonderti quando leggi quel pezzo di codice la prossima volta:

if someBoolValue: num1=20

Non sono un grande fan di num1 = someBoolValue and 20 or num1 per lo stesso identico motivo. Devo davvero pensarci due volte su cosa sta facendo quella linea.

Il modo migliore per ottenere effettivamente quello che vuoi fare è la versione originale:

if someBoolValue:
    num1 = 20

La ragione per cui è la migliore versione è perché è molto ovvio ciò che vuoi fare e non ti confonderai, o chiunque altro entrerà in contatto con quel codice in seguito.

Inoltre, come nota a margine, num1 = 20 if someBoolValueè un codice Ruby valido, perché Ruby funziona in modo leggermente diverso.


8
Secondo PEP-308 ( docs.python.org/2.5/whatsnew/pep-308.html ), l'espressione condizionale può essere resa più chiara se messa in parentesi, come in num1 = (20 if someBoolValue else num1).
Haridsv,

46

Usa questo:

num1 = 20 if someBoolValue else num1

3
questo è quello che ho usato .. e cerco un'alternativa .. grazie comunque !!
bdhar,

Come chiamare questo blocco? Voglio dire come si chiama?
fuat

1
è un operatore ternario
Chris Maes il

Non si dovrebbe usare questo approccio se si esegue il ciclo attraverso set di dati di grandi dimensioni poiché introduce un'assegnazione non necessaria nel caso in cui finiamo nell'istruzione else.
dapc,

21

In una riga:

if someBoolValue: num1 = 20

Ma non farlo. Questo stile normalmente non è previsto. Le persone preferiscono la forma più lunga per chiarezza e coerenza.

if someBoolValue:
    num1 = 20

(Allo stesso modo, i cappelli dei cammelli dovrebbero essere evitati. Quindi piuttosto usare some_bool_value.)

Si noti che un'espressione in linea some_value if predicatesenza una elseparte non esiste perché non ci sarebbe un valore di ritorno se il predicato fosse falso. Tuttavia, le espressioni devono avere un valore di ritorno chiaramente definito in tutti i casi. Questo è diverso dall'uso come in, diciamo, Ruby o Perl.


2
Perché diventa difficile da leggere e probabilmente finirai per essere confuso dal tuo codice, e non è mai una buona idea.
Gelo,

@bdhar, perché vuoi metterlo su una riga? Non correrà più veloce, sarà solo più difficile per gli altri leggere
John La Rooy,

1
@gnibbler, nessun motivo, in realtà. stavo cercando una forma più breve con una migliore leggibilità ..
bdhar

17

puoi usare uno dei seguenti:

(falseVal, trueVal)[TEST]

TEST and trueVal or falseVal

1
Nice one liner condizionale
task

Come si chiama quella "struttura"? Non l'ho mai visto in ~ 6 mesi di apprendimento di Python.
Guimoute,

1
Almeno questi non sono incarichi, a meno che tu non li metta di fronte a loro, e in secondo luogo, non funzioneranno nel modo descritto qui. Il primo crea una tupla, quindi seleziona uno dei suoi elementi per indice. Funzionerà solo per i test che restituiscono un numero intero compreso tra -1 e 1 o True/ False, poiché boolè una sottoclasse di int. In tutti i casi in cui il test restituisce qualcosa che valuterà semplicemente vero, fallisce con un'eccezione. Il secondo funziona solo a condizione che trueValnon valuti il ​​falso stesso, il che si tradurrebbe in falseValessere assegnato anche se il test fosse vero.
Bachsau,

è ben breve, ma anche molto complicato da usare in modo sicuro come "schema raccomandato", vedi il commento sopra di Bachsau ... (quindi l'ho
sottoposto a downgrade

6

No. Immagino tu sperassi che qualcosa del genere num1 = 20 if someBoolValueavrebbe funzionato, ma non funziona. Penso che il modo migliore sia con l' ifaffermazione come l'hai scritta:

if someBoolValue:
    num1 = 20

5
num1 = 10 + 10*(someBoolValue is True)

Questa è la mia nuova risposta finale. La risposta precedente era la seguente ed era eccessiva per il problema dichiarato. Getting_too_clever == not Good. Ecco la risposta precedente ... ancora buona se vuoi aggiungere una cosa per Truecond e un'altra per False:

num1 = 10 + (0,10)[someBoolValue is True]

Hai num1già detto che avrebbe già un valore che dovrebbe essere lasciato solo. Ho assunto num1 = 10dal momento che questa è la prima dichiarazione del post, quindi l'operazione da raggiungere 20è quella di aggiungere 10.

num1 = 10
someBoolValue = True

num1 = 10 + (0,10)[someBoolValue is True]

print(f'num1 = {num1}\nsomeBoolValue = {someBoolValue}')

prodotto questo output

num1 = 20
someBoolValue = True

Ora sto pensando che avrei dovuto rispondere "num1 = 10 + 10 * (someBoolValue == True)" Problema definito fondamentalmente come condizione "Falso" come no-op. Se fosse necessario scegliere se aggiungere un valore diverso per "Falso", la risposta precedente è più adatta. Modifico il mio post o lo faccio nei commenti?
MikeyB,


2

Se desideri invocare un metodo se un valore booleano è vero, puoi mettere else Nonefine al trinario.

>>> a=1
>>> print(a) if a==1 else None
1
>>> print(a) if a==2 else None
>>> a=2
>>> print(a) if a==2 else None
2
>>> print(a) if a==1 else None
>>>

1

Se un codice di riga sta per accadere, Python 3.8 introduce espressioni di assegnazione affettuosamente conosciute come "l'operatore tricheco".

:=

someBoolValue and (num := 20)

La 20saranno assegnati a numse la prima espressione booleana è True. L'assegnazione deve essere tra parentesi qui, altrimenti verrà visualizzato un errore di sintassi.

num = 10
someBoolValue = True

someBoolValue and (num := 20)
print(num) # 20

num = 10
someBoolValue = False

someBoolValue and (num := 20)
print(num) # 10

0

Per il futuro viaggiatore nel tempo di Google, ecco un nuovo modo (disponibile da Python 3.8 in poi):

b = 1
if a := b:
    # this section is only reached if b is not 0 or false.
    # Also, a is set to b
    print(a, b)


-1

Ecco cosa posso suggerire. Utilizzare un'altra variabile per derivare la clausola if e assegnarla a num1.

Codice:

num2 =20 if someBoolValue else num1
num1=num2


-1

Puoi farlo in questo modo.

try:
    a = [i for i in [20] if False][0]
except IndexError:
    print("Do what ever you want here")

Puoi risolvere il tuo problema in questo modo ma, usando 'try / tranne block' non è la migliore pratica per Python.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.