Existe-t-il un moyen plus court d'attribuer l'une des deux variables en Python?

19

C'est une question de pour jouer au golf en .

Dans plusieurs golfs que j'ai effectués en Python, une valeur fixe est affectée à l'une des deux variables choisies par un booléen. La variable choisie est remplacée par la valeur donnée, et l'autre est inchangée.

17 caractères:

if b:y=z
else:x=z

L'attribution d'une valeur conditionnelle est facile , mais l'attribution à une variable conditionnelle semble maladroite. Je me demande s'il y a un moyen plus court de me manquer.

Ce serait facile s'il x,ys'agissait plutôt d'une liste L, mais supposons que le contexte nécessite de se référer suffisamment aux variables pour écrire L[0]et L[1]est prohibitif. La conversion prend trop de temps:

20 caractères:

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

Le moyen le plus rapide que je connaisse est avec un Python 2 exec, ce qui est bizarre:

16 caractères, Python 2:

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

Le choix des tuples semble être plus long:

18, 19, 18, 18 caractères:

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-t-il une méthode plus courte ou une optimisation pour économiser les caractères? Vous pouvez supposer que bc'est 0ou 1pas seulement Falsey ou Truthy, et aussi faire des hypothèses sur les types de données et les valeurs si cela vous aide.

xnor
la source
1
Je ne connais rien de mieux. Si vous avez besoin de faire beaucoup de choses, vous pouvez le faire x,y=C(x,y,z,b)(14 caractères) et pousser n'importe laquelle de ces implémentations dans le corps de C.
Keith Randall
Pourquoi n'est-ce pas dans Stack Overflow?
BobTheAwesome
14
@BobTheAwesome Je ne demande pas de bons moyens de le faire, juste de courts.
xnor

Réponses:

26

12 caractères / affectation + 9 caractères de frais généraux

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

Notez que cela ne fonctionne qu'à portée globale, cela ne fonctionne pas à l'intérieur d'une fonction.

Keith Randall
la source
1
Wow, je n'en savais rien. Et c'est cool de se mettre à Vjour automatiquement, sans avoir besoin d'appeler à nouveau la fonction. Donc, cela rompt avec execdeux utilisations. En outre, il suffit de vars()["xy"[b]]=z17 caractères, ce qui est le meilleur que nous ayons jusqu'à présent pour Python 3, sans que le flux de contrôle if/elsepuisse causer des problèmes.
xnor
3
Il s'agit en fait de 9 caractères de surcharge car un saut de ligne ou un point-virgule doit suivre l'affectation.
2015
1
Si vous ne devez le faire qu'une seule fois, pouvez-vous faire vars()["xy"[b]]=z:?
aebabis
@acbabis: oui, comme l'a souligné xnor.
Keith Randall
19

14 caractères, Python 2

exec"xy=z"[b:]

Les deux variables sont yet xy. Si b = 0, cela définit xy=z. Si b = 1, cela définit y=z. Cela en vaudra la peine s'il xyn'est utilisé qu'une seule fois ailleurs dans le code.

isaacg
la source
2
Très intelligent! Je soupçonne cependant que vous devez généralement utiliser xyau moins deux fois, pour son affectation initiale, et le lire ensuite.
xnor
15

15 caractères, Python 2

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

Nécessite que les variables soient appelées Fet Tplutôt que xet y, et que b is Falseou b is True, plutôt que d'être des nombres égaux 0ou 1.

Cela enregistre un caractère "xy"[b]en prenant à la place la première lettre de la représentation sous forme de chaîne b, qui est Tou F.

xnor
la source
7
Notez que les variables peuvent également être appelées aet r, let uou set e, avec des indices appropriés.
isaacg