Pitone:evitando la condizione if?
-
19-09-2019 - |
Domanda
Che è migliore?
if not var:
var = get_var()
(O)var = var o get_var()
Inoltre, come faccio a sapere qual è il migliore tra i due?
modificare:
Un'altra opzione da parte di Steve,
var = var if var else get_var()
Soluzione
Meglio è quello che ti piace di più.Vorrei utilizzare la prima versione con if
ma questo è molto personale.
Altri suggerimenti
Quando due varianti di stile sono così vicine stilisticamente, utilizzo timeit
come spareggio:più veloce deve significare più vicino al mainstream di Python, cioè migliore.Ehi, è meglio di un dibattito senza fine, vero?-) Quindi:
$ python -mtimeit -s'var=0; getvar=lambda:0' 'var = var or getvar()'
1000000 loops, best of 3: 0.359 usec per loop
$ python -mtimeit -s'var=0; getvar=lambda:0' 'if not var: var = getvar()'
1000000 loops, best of 3: 0.361 usec per loop
$ python -mtimeit -s'var=1; getvar=lambda:1' 'var = var or getvar()'
10000000 loops, best of 3: 0.123 usec per loop
$ python -mtimeit -s'var=1; getvar=lambda:1' 'if not var: var = getvar()'
10000000 loops, best of 3: 0.0899 usec per loop
IL if
ce l'ha - equivalente a quando var
è falso, più veloce quando lo è true
.
In realtà, se stai cercando di determinare se var è stato precedentemente impostato utilizzando una chiamata a get_var, allora direi che entrambe le forme sono sbagliate.Python tratta un numero di valori perfettamente ordinari come valutati come booleani "falsi":0, Nessuno, [], (,), set() e {}.Quindi diciamo che var sarà un numero intero e get_var() sembra restituire 0.Ora, indipendentemente dalla forma utilizzata, get_var() verrà chiamata ancora e ancora, anche se sappiamo già che var è 0!
Esistono diversi metodi per rilevare se una variabile è stata definita o meno:
guarda nel dict restituito da globals() o locals()
avvolgere la dichiarazione
var = var
in un blocco try/eccetto, intrappolando NameErrorusa un valore sentinella come None e inizializza var su questo valore;allora puoi fare il test
if var is None: var = get_var()
(usando 'is', non '==').Se sei sfortunato e None è un potenziale valore da restituire da get_var(), allora dovrai definire il tuo valore speciale non ancora definito, usando qualcosa comeNOT_DEFINED = object()
, inizializza var con esso e quindi puoi testareif var is NOT_DEFINED
.
Per me il primo modo di dire, quello che usa il se esplicito, è preferibile perché più esplicito.
Tuttavia ho visto che il costrutto o viene fatto riferimento come quello preferito/più pitonico.
Quindi, da un lato, Explicit is better than implicit
(citazione Zen), d'altra parte, l'espressione breve può essere vista come pitonica (sebbene più breve non equivalga a pitonica in tutti i casi!)
Una domanda SO strettamente correlata è il modo più idiomatico per convertire None in una stringa vuota, e lì erano elencati sia gli idiomi if che gli idiomi or.
la prima versione è più intuitiva per me.Ma poi di nuovo, è tutta una questione di gusti.
Il secondo è più Pythonic e normalmente lo uso.
Nessuno dei due è sbagliato.
Il primo è più chiaro da comprendere per qualcuno che legge il codice.
Chiediti se, quando pensi al problema che stai cercando di risolvere, i concetti che ti vengono in mente sono più vicini a "se questo, allora quello" o "un OR logico di due variabili quasi, ma non del tutto, booleane".
Entrambi verranno eventualmente compilati nello stesso codice, dato che o è un operatore di cortocircuito (non valuta l'argomento della mano destra se la mano sinistra è vera).
Preferirei il primo perché esprime più chiaramente le tue intenzioni.Il secondo è probabilmente più compatto.
L'interprete probabilmente li eseguirà in entrambi i modi.Esistono dei compromessi per quanto riguarda la leggibilità del codice.Quale affermazione è più facile riconoscere cosa fa?Certamente la prima è molto più chiara.Per quanto mi riguarda, leggendo questo post, ho dovuto pensare di più al secondo.Utilizzerei la prima per una maggiore leggibilità, anche se la seconda affermazione è leggermente più "sexy".
Spero che questo ti aiuti.
-tjw