Existe uma maneira mais curta de atribuir uma das duas variáveis ​​no Python?

19

Esta é uma pergunta de para jogar golfe em .

Em vários campos de golfe que fiz em Python, um valor fixo é atribuído a uma das duas variáveis ​​escolhidas por um booleano. A variável escolhida é substituída pelo valor fornecido e a outra é inalterada.

17 caracteres:

if b:y=z
else:x=z

É fácil atribuir um valor condicional , mas atribuir a uma variável condicional parece desajeitado. Eu estou querendo saber se há uma maneira mais curta que eu estou perdendo.

Isso seria fácil se x,yfosse uma lista L, mas suponha que o contexto exija referência suficiente às variáveis ​​que a escrita L[0]e L[1]é proibitiva. A conversão leva muito tempo:

20 caracteres:

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

A maneira mais rápida que conheço é com um Python 2 exec, que é bizarro:

16 caracteres, Python 2:

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

A escolha da tupla parece ser mais longa:

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 

Existe algum método mais curto ou otimização para salvar caracteres? Você pode assumir que bé 0ou 1não apenas Falsey ou Truthy, e também fazer suposições sobre os tipos e valores de dados, se isso ajudar.

xnor
fonte
11
Não conheço nada melhor. Se você precisar fazer muito isso, poderá fazer x,y=C(x,y,z,b)(14 caracteres) e inserir qualquer uma dessas implementações no corpo do C.
Keith Randall
Por que isso não está no Stack Overflow?
BobTheAwesome
14
@BobTheAwesome Não estou pedindo boas maneiras de fazer isso, apenas pequenas.
Xnor

Respostas:

26

12 caracteres / atribuição + 9 caracteres de sobrecarga

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

Observe que isso funciona apenas no escopo global, não funciona dentro de uma função.

Keith Randall
fonte
11
Uau, eu não sabia disso. E é legal que Vatualize automaticamente, sem a necessidade de chamar a função novamente. Portanto, isso se quebra execem dois usos. Além disso, apenas vars()["xy"[b]]=z17 caracteres são o melhor que temos até agora para o Python 3, sem o fluxo de controle if/elseque pode causar problemas.
Xnor
3
Na verdade, são 9 caracteres de sobrecarga, porque uma nova linha ou ponto e vírgula deve seguir a tarefa.
xnor
11
Se você precisar fazer apenas uma vez, você pode vars()["xy"[b]]=z:?
aebabis
@acbabis: sim, como o xnor apontou.
Keith Randall
19

14 caracteres, Python 2

exec"xy=z"[b:]

As duas variáveis ​​são ye xy. Se b = 0, isso define xy=z. Se b = 1, isso define y=z. Isso valerá a pena se não for xyusado mais de uma vez em outra parte do código.

isaacg
fonte
2
Muito esperto! Eu suspeito que você geralmente precise usar xypelo menos duas vezes, para sua atribuição inicial, e para ler depois.
Xnor
15

15 caracteres, Python 2

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

Requer que as variáveis ​​sejam chamadas Fe em Tvez de xe y, e que b is Falseou b is True, em vez de serem os números iguais 0ou 1.

Isso evita que um caractere pegue "xy"[b]a primeira letra da representação de sequência de b, que é Tou F.

xnor
fonte
7
Observe que as variáveis ​​também podem ser chamadas ae r, le uou se e, com índices apropriados.
Isaacg