2009-11-22 18 views
17

In alcune parti del mio programma Python ho una variabile val che può essere 1 o 0. Se è 1 devo passare a 0, se è 0 devo passare a 1.Scambio 1 con 0 e 0 con 1 in modo Pythonic

Come si fa in modo pitadico?

if val == 1: 
    val = 0 
elif val == 0: 
    val = 1 

è troppo lungo!

ho fatto:

swap = {0: 1, 1:0} 

così posso usarlo:

swap[val] 

Altre idee?

+6

C'è un motivo per non usare 'true' /' false' invece di '1'/'0' nel tuo caso? – jfs

+2

Il modo più pitonico per fare ciò prenderebbe in considerazione il significato della variabile. È numerico? Booleano (vale a dire vero/falso)? Ha qualche significato semantico che non è ovvio qui? Il solo fatto che tu voglia commutarlo implica che abbia qualche significato ... che cos'è? –

+0

Penso che il termine che stai cercando sia "toggle". –

risposta

91

Questo non è pitonico, ma è un linguaggio neutro. Spesso val = 1 - val è il più semplice.

+28

È troppo leggibile! Vai per 'val^= 1'! – abyx

+7

Questo è intelligente, ma richiede che la persona che legge il tuo codice pensi (probabilmente), il che potrebbe costringerti ad aggiungere un commento. Mi piace il ternario meglio ad es. val = 0 se val else 1 perché dice esattamente cosa fa. – rplevy

+2

Un altro modo di dire la stessa cosa: var = ((var + 1) & 1). – MAK

20

Dal True == 1 e False == 0 in python,

si potrebbe utilizzare var = not var

Sarà solo scambiarlo.

+0

non 1 == Falso, non 0 == Vero –

+0

Questo sembra un dettaglio di implementazione e non può fare affidamento su di esso. –

+0

ma 'int (not 1) == 0' e' int (not 0) == 1' perché 'int (True) == 1' e' int (False) == 0'. e questo probabilmente non è un dettaglio di implementazione. –

1

Se si vuole essere breve:

f = lambda val: 0 if val else 1 

Poi:

>>> f(0) 
1 
>>> f(1) 
0 
5

Nel tuo caso vi consiglio il ternario:

val = 0 if val else 1 

Se dovessi 2 variabili per scambiare voi Potrei dire:

(a, b) = (b, a) 
+0

OP non ha due valori da scambiare. ha un singolo valore che vuole cambiare – SilentGhost

+0

Aggiunta una modifica. Ternario ha più senso qui. – rplevy

9

Solo un'altra possibilità:

i = (1,0)[i] 

Questo metodo funziona bene finché i è positivo, come dbr rilevare nei commenti non funziona falliscono per i < 0.

Sei sicuro non vuoi usare False e True? Sembra quasi come

+0

Non si errore se 'i' è' -1' o '-2', e si comporterebbe in modo strano. '{0: 1, 1: 0} [i]' verrebbe comunque errore – dbr

+0

@dbr grazie. Volevo includere questo nella risposta, ma poi ho visto che l'OP aveva già trovato questa risposta. Mi sto attenendo a quello che ho perché è davvero compatto. –

12

L'approccio più breve utilizza l'operatore bitmap XOR.

Se si desidera val per essere riassegnato:

val ^= 1 

Se non si desidera val essere riassegnato:

val^1 
+0

Mi piace questa risposta perché offre l'opportunità di fare lo scambio dinamicamente, usando "'^1' "o" '^ 0'", con quest'ultimo che non porta a scambio. –

0

Funzione con argomento mutevole. Chiamando il numero swaper() verrà restituito un valore diverso ogni volta.

def swaper(x=[1]): 
    x[0] ^= 1 
    return x[0] 
0

Solo un altro modo:

val = ~val + 2 
1

(0,1) [non val] inverte la val da 0 a 1 e viceversa.

+0

['not val'] (http://stackoverflow.com/a/1779305/4279) * da solo * ribalta il valore da' 0' a '1'. Nota: 'False == 0' e' 1 == True' in Python. – jfs

1

di estendere il answer by "YOU", utilizzare:

int(not(val)) 

Esempi:

>>> val = 0 
>>> int(not(val)) 
1 
>>> val = 1 
>>> int(not(val)) 
0 

Si noti che questa risposta ha il solo scopo descrittivo, non prescrittivo.

0

Il tuo modo funziona bene!

Che dire:

val = abs(val - 1) 

breve e semplice!

0

Il modo più divinatorio sarebbe probabilmente

int(not val) 

Ma un modo più breve sarebbe

-~-val