Is there a shorter way to assign one of two variables in Python?

19

This is a question for golfing in .

In multiple golfs I've done in Python, a fixed value is assigned to one of two variables chosen by a Boolean. The chosen variable is overwritten by the given value, and the other is unchanged.

17 chars:

if b:y=z
else:x=z

Assigning a conditional value is easy, but assigning to a conditional variable seems clunky. I'm wondering if there's a shorter way I'm missing.

This would be easy if x,y were instead a list L, but assume the context requires referring to the variables enough that writing L[0] and L[1] is prohibitive. Converting takes too long:

20 chars:

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

The fastest way I know is with a Python 2 exec, which is bizarre:

16 chars, Python 2:

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

Tuple-choosing seems to be longer:

18, 19, 18, 18 chars:

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 

Is there some shorter method or character-saving optimization? You can assume b is 0 or 1, not just Falsey or Truthy, and also make assumptions about the data types and values if it helps.

xnor

Posted 2015-03-10T20:01:30.890

Reputation: 115 687

1I don't know of anything better. If you need to do this a lot, you can do x,y=C(x,y,z,b) (14 chars) and push any of these implementations into the body of C. – Keith Randall – 2015-03-10T20:49:48.883

Why isn't this in Stack Overflow? – BobTheAwesome – 2015-03-10T21:32:16.850

14@BobTheAwesome I'm not asking for good ways to do this, just short ones. – xnor – 2015-03-10T21:32:55.507

Answers

26

12 chars/assignment + 9 chars of overhead

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

Note that this only works at global scope, it does not work inside a function.

Keith Randall

Posted 2015-03-10T20:01:30.890

Reputation: 19 865

1Wow, I did not know about this. And it's cool that V updates automatically, with no need to call the function again. So this breaks even with exec in two uses. Also, just doing vars()["xy"[b]]=z is 17 chars, which is the best we have so far for Python 3, without the control flow of if/else which can cause problems. – xnor – 2015-03-10T21:26:27.577

3It's actually 9 chars of overhead because a newline or semicolon must follow the assignment. – xnor – 2015-03-11T00:30:54.567

1If you only need to do it once, can you do: vars()["xy"[b]]=z? – aebabis – 2015-03-11T19:37:18.480

@acbabis: yes, as xnor pointed out. – Keith Randall – 2015-03-11T22:06:22.643

19

14 chars, Python 2

exec"xy=z"[b:]

The two variables are y and xy. If b=0, this sets xy=z. If b=1, this sets y=z. This will be worth it if xy is used no more than once elsewhere in the code.

isaacg

Posted 2015-03-10T20:01:30.890

Reputation: 39 268

2Very clever! I suspect you usually need to use xy at least twice though, for its initial assignment, and to read it out afterwards. – xnor – 2015-03-10T21:27:18.727

15

15 chars, Python 2

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

Requires that the variables be called F and T rather than x and y, and that b is False or b is True, rather than being the equal numbers 0 or 1.

This saves a char from "xy"[b] by instead taking the first letter of the string representation of b, which is T or F.

xnor

Posted 2015-03-10T20:01:30.890

Reputation: 115 687

7Note that the variables can also be called a and r, l and u or s and e, with appropriate indices. – isaacg – 2015-03-11T07:18:38.803