¿Hay una forma más corta de asignar una de dos variables en Python?

19

Esta es una pregunta de para jugar golf en .

En varios campos de golf que he hecho en Python, se asigna un valor fijo a una de las dos variables elegidas por un booleano. La variable elegida se sobrescribe por el valor dado, y la otra no se modifica.

17 caracteres:

if b:y=z
else:x=z

Asignar un valor condicional es fácil , pero asignarlo a una variable condicional parece torpe. Me pregunto si hay un camino más corto que me falta.

Esto sería fácil si x,yfuera una lista L, pero suponga que el contexto requiere referirse a las variables lo suficiente como para escribir L[0]y L[1]es prohibitivo. La conversión lleva demasiado tiempo:

20 caracteres:

L=[x,y];L[b]=z;x,y=L

La forma más rápida que conozco es con un Python 2 exec, lo cual es extraño:

16 caracteres, Python 2:

exec"xy"[b]+"=z"

La elección de tuplas parece ser más larga:

18, 19, 18, 18 caracteres:

x,y=b*(x,z)or(z,y)
x,y=[z,x,y,z][b::2]
y,x=[y,z,x][b:b+2]
y,x,*_=[y,z,x][b:]   # Python 3 

¿Hay algún método más corto u optimización de ahorro de caracteres? Puede suponer que bes 0o 1, no solo Falsey o Truthy, y también hacer suposiciones sobre los tipos y valores de datos si es útil.

xnor
fuente
1
No conozco nada mejor. Si necesita hacer esto mucho, puede hacer x,y=C(x,y,z,b)(14 caracteres) e insertar cualquiera de estas implementaciones en el cuerpo de C.
Keith Randall
¿Por qué no está esto en Stack Overflow?
BobTheAwesome
14
@BobTheAwesome No estoy pidiendo buenas formas de hacer esto, solo algunas cortas.
xnor

Respuestas:

26

12 caracteres / asignación + 9 caracteres de sobrecarga

V=vars()     # do once at the start of the program
V["xy"[b]]=z

Tenga en cuenta que esto solo funciona a nivel global, no funciona dentro de una función.

Keith Randall
fuente
1
Wow, no sabía sobre esto. Y es genial que se Vactualice automáticamente, sin necesidad de volver a llamar a la función. Entonces esto se iguala con execdos usos. Además, solo vars()["xy"[b]]=zhay 17 caracteres, que es lo mejor que tenemos hasta ahora para Python 3, sin el flujo de control if/elseque puede causar problemas.
xnor
3
En realidad, son 9 caracteres de sobrecarga porque una nueva línea o punto y coma debe seguir la asignación.
xnor
1
Si solo necesita hacerlo una vez, ¿puede hacer vars()["xy"[b]]=z:?
aebabis
@acbabis: sí, como señaló xnor.
Keith Randall
19

14 caracteres, Python 2

exec"xy=z"[b:]

Las dos variables son yy xy. Si b = 0, esto establece xy=z. Si b = 1, esto establece y=z. Esto valdrá la pena si no xyse usa más de una vez en otra parte del código.

isaacg
fuente
2
¡Muy inteligente! Sin xyembargo, sospecho que generalmente necesita usar al menos dos veces, para su asignación inicial, y leerlo después.
xnor
15

15 caracteres, Python 2

exec`b`[0]+"=z"

Requiere que las variables se llamen Fy en Tlugar de xy y, y eso b is Falseo b is True, en lugar de ser números iguales 0o 1.

Esto ahorra un carácter "xy"[b]al tomar la primera letra de la representación de cadena de b, que es To F.

xnor
fuente
77
Tenga en cuenta que las variables también se pueden llamar ay r, ly uo sy e, con los índices apropiados.
isaacg