2012-04-08 14 views
9

spesso finiscono per scrivere codice comeIn Python quali sono altri modi per scrivere a if x == 1 o x == 5 o x == 10 ...?

if x == 1 or x == 5 or x == 10 or x == 22 : 
    pass 

In inglese sembra superfluo continuare a ripetere x, c'è un modo più semplice o più corta di scrivere una dichiarazione se-like che?

Forse verificare l'esistenza del valore di x in una tupla (1, 5, 10, 22,) o qualcosa del genere?

+2

Sì, 'se x in [1, 50, 10, 22]' è più semplice da scrivere e leggi –

risposta

14

Sì, hai ragione - in una tupla o (se questo controllo è ripetuto più volte) in un set.

Quindi, o fare

if x in (1, 5, 10, 22): 
    pass 

o, se si esegue questa verifica spesso e il numero di valori è abbastanza grande,

myset = set((1, 5, 10, 22)) 

[...] 

if x in myset: 
    pass 

La roba myset è il più utile, più valori voglio controllare. 4 valori sono abbastanza pochi, quindi puoi mantenerlo semplice. 400 valori e si dovrebbe usare il set ...

Un altro aspetto, come sottolineato da Marcin, è l'hashing necessario per la ricerca nel set che può essere più costoso della ricerca lineare di una lista o di una tupla per il valore desiderato.

+7

In Python 2.7/3. *, puoi anche usare un letterale set: '{1, 5, 10, 22}'. In Python 3.2+, questo ottimizza anche l'uso di un 'frozenset' in modo trasparente se si sta solo eseguendo un controllo' 'in '(anche se non se si salva il risultato in una variabile). – Dougal

+2

+1 per suggerire per prima cosa set, ma devo essere d'accordo con Dougal sul fatto che dovresti usare la nuova sintassi se possibile. –

+1

'set ((1, 5, 10, 22))' funziona in più versioni di '{1, 5, 10, 22}' e in realtà non è tutto ciò che è più leggibile. – martineau

6

È possibile utilizzare in con una collezione:

if x in [1, 5, 10, 22]: 
    # etc... 

if x in {1, 5, 10, 22}: # New syntax for creating sets 
    # etc... 

Si noti che questo creerà un nuovo elenco ogni volta che la linea viene eseguito. Se l'efficienza è un problema, crea la raccolta una sola volta e riutilizzala.

+0

... o un set, come ho scritto. Non così urgente con 4 valori, più urgente con 40, 400 o 4000 ... – glglgl

+0

Tuttavia, una tupla è più comune e un set è semanticamente più bello anche scontando le prestazioni che entrambi hanno (a seconda della versione di Python in quest'ultimo caso) . – delnan

+0

@glglgl: Oh sì, un set è un'idea migliore. La tupla è comunemente usata, ma penso che non sia semanticamente il tipo più appropriato. –

2

Se avete bisogno di buone prestazioni e si sta per ripetere lo stesso confronto più volte, utilizzare un set:

s = frozenset([1, 5, 10, 22]) # at the beginning 

if x in s: # in your code 
    pass 
+3

Ovviamente, per piccoli set di dati una tupla può essere più veloce (non c'è bisogno di hash, struttura dei dati più semplice, nessun rischio di collisione) e in Python 3.2, si ottiene questa ottimizzazione gratuitamente (ancora meglio, il frozenset viene creato una sola volta) se usi un set letterale nella condizione. Inoltre, gli stessi termini e condizioni di tutti i problemi di prestazioni: (1) Misurare se è necessario ottimizzare questo. (2) Ancora # 2! (3) Veramente sicuro? (4) Bene, bene! Vai a raccogliere le tue scelte e confrontarle bene. – delnan

+0

Quindi creare un 'frozenset' è più veloce della creazione di un' elenco' regolare e di un 'set'? – George