2009-11-22 19 views
17

En alguna parte de mi programa Python tengo una variable val que puede ser 1 o 0. Si es 1 debo cambiar a 0, si es 0 debo cambiar a 1.Intercambiando 1 con 0 y 0 con 1 de forma Pythonic

¿Cómo lo haces de forma pitonica?

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

¡es demasiado largo!

lo hice:

swap = {0: 1, 1:0} 

, así que puede usarlo:

swap[val] 

Otras ideas?

+6

¿Hay una razón para no usar 'TRUE/FALSE en lugar de' 1'/'0' en tu caso? – jfs

+2

La forma más pitonica de hacer esto tendría en cuenta el significado de la variable. ¿Es numérico? Booleano (es decir, verdadero/falso)? ¿Tiene algún significado semántico que no es obvio aquí? El solo hecho de que quiera alternarlo implica que tiene algún significado ... ¿qué es? –

+0

Creo que el término que está buscando es "alternar". –

Respuesta

91

Esto no es pitónico, pero es un lenguaje neutral. A menudo val = 1 - val es más simple.

+28

¡Eso es muy legible! Ir por 'val^= 1'! – abyx

+7

Eso es inteligente, pero requiere que la persona que lee tu código piense (probablemente), lo que puede obligarte a agregar un comentario. Me gusta el ternario mejor, por ejemplo. val = 0 si val else 1 porque dice exactamente lo que hace. – rplevy

+2

Otra forma de decir lo mismo: var = ((var + 1) & 1). – MAK

20

Desde True == 1 y False == 0 en Python,

es posible que utilices var = not var

Será simplemente intercambiarlo.

+0

no 1 == Falso, no 0 == Verdadero –

+0

Parece un detalle de implementación y no puede confiar en él. –

+0

pero 'int (not 1) == 0' y' int (not 0) == 1' porque 'int (True) == 1' y' int (False) == 0'. y este probablemente no sea un detalle de implementación. –

1

Si quieres ser corto:

f = lambda val: 0 if val else 1 

continuación:

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

En su caso recomiendo el ternario:

val = 0 if val else 1 

Si tuviera 2 variables para intercambiar usted podría decir:

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

OP no tiene dos valores para intercambiar. tiene un valor único que quiere cambiar – SilentGhost

+0

Se ha agregado una edición. El ternario tiene más sentido aquí. – rplevy

9

Sólo otra posibilidad:

i = (1,0)[i] 

Esto funciona bien siempre que i es positivo, ya que dbr señaló en los comentarios que no funciona fallan para i < 0.

¿Seguro usted no desea usar False y True? Suena casi como eso.

+0

No se producirá un error si 'i' es' -1' o '-2', y actuaría de manera extraña. '{0: 1, 1: 0} [i]' sería un error, sin embargo, – dbr

+0

@dbr gracias. Quería incluir esto en la respuesta, pero luego vi que el OP ya había encontrado esta respuesta. Me estoy quedando con el que tengo porque es muy compacto. –

12

El enfoque más corto es utilizar el operador de bit a bit XOR.

Si desea val ser reasignado:

val ^= 1 

Si no desea volver a ser destinado a val:

val^1 
+0

Me gusta esta respuesta porque ofrece la oportunidad de realizar el intercambio de forma dinámica, utilizando "'^1' "o" '^ 0'", lo que no da lugar a ningún intercambio. –

0

función con el argumento mutable. Llamar al swaper() devolverá un valor diferente cada vez.

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

Sólo otra manera:

val = ~val + 2 
1

(0,1) [no val] voltea la val de 0 a 1 y viceversa.

+0

['not val'] (http://stackoverflow.com/a/1779305/4279) * por sí mismo * invierte el valor de' 0' a '1'. Nota: 'False == 0' y' 1 == True' en Python. – jfs

1

de ampliar la answer by "YOU", utilice:

int(not(val)) 

Ejemplos:

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

Tenga en cuenta que esta respuesta sólo está destinado a ser descriptiva y no prescriptiva.

0

¡Tu camino funciona bien!

¿Qué hay de:

val = abs(val - 1) 

corto y sencillo!

0

La forma más Pythonic probablemente sería

int(not val) 

Pero un camino más corto sería

-~-val