3

I know that you can do things like this in Python:

var = value1 if( booleanCheck() ) else value2

What I want to know is if I can conditionally choose which var I place a value into with a similar sort of structure?

something like this:

(var1 if( booleanCheck() ) else var2) = value

In my case specifically I'm trying to assign a child node to the correct side in a Binary Search Tree, I know I can just do a normal if block but I was trying to challenge myself to using minimal space.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
user2614726
  • 131
  • 1
  • 4

4 Answers4

4

Well theoretically you could do something like this, if both variables are already defined:

var1, var2 = (value, var2) if booleanCheck() else (var1, value)

Not saying that you should do it, though.

w-m
  • 10,772
  • 1
  • 42
  • 49
2

Since the use case is assigning to the correct side of a binary tree, I assume the assignment targets are actually attributes of some tree node, and the usual code would be

if condition:
    node.left = value
else
    node.right = value

This code could be replaced by

setattr(node, "left" if condition else "right", value)

or alternatively

vars(node)["left" if condition else "right"] = value

It could be replaced by this, but it really shouldn't.

Sven Marnach
  • 574,206
  • 118
  • 941
  • 841
1

It's not very good form to use locals or globals in this way (confusing, not often used, hard to debug, terrible performance), but it can be done:

varname = 'a' if some_condition else 'b'
locals()[varname] = value # or globals()
print locals()[varname] # or globals()

I think the real challenge here is to resist seemingly "fancy" or "creative" code and write code that others will understand immediately. Not to mention yourself if you have to come back to it later. But it is worth it to know what funky code (as in old cheese) looks like.

mdscruggs
  • 1,182
  • 7
  • 15
  • 1
    You can't modify the dictionary returned by `locals()`. It might work in some cases, like in the global scope, but in general it doesn't, see the [documentation](http://docs.python.org/2/library/functions.html#locals). – Sven Marnach Jul 24 '13 at 13:51
  • I don't think that's right. In my 2.7.5 interpreter, I can write a function that writes a new key:value pair and reads the value, both using `locals()`. Could you explain where it doesn't work? – mdscruggs Jul 24 '13 at 13:56
  • 1
    In general, it doesn't work whenever you are inside a function using fast locals (most functions not using `exec` fall into this category). Moreover, it doesn't matter whether you find a specific version of a specific Python implementation that happens to execute this code in the way you expect -- the language specification says you can't do this, so you can't rely on this to work portably. – Sven Marnach Jul 24 '13 at 14:00
  • Thanks for editing your comment with the docs link. But obviously I recommended the OP not use this approach anyway (as everyone else has as well). – mdscruggs Jul 24 '13 at 14:03
0

Unlike locals(), globals() is documented to be updateable (as it returns the __dict__ of the current module). I routinely use vars() in the global scope - which is the same in that case - to reduce code duplication:

for v,ar in ('a',x),('b',y): vars()[v]=fn(ar)

For some others objects (like the current class/instance), __dict__'s members are accessible as syntactic variables, too:

class C:
    def __init__(self,a,b):
        vars(self).update(v,locals()[v] for v in 'a','b')
        do_something(self.a)

Do note, however, that:

  • These "syntactic references" reduce code maintainability - as they are harder to find - and thus will likely upset code checking tools like pylint.
  • a need to use variables in such a way typically signifies an attempt to use a scope as a dict: such variables tend to be "homogenous" in some way, asking for being used in array operations, and thus should probably be combined into a dedicated container instead.
Community
  • 1
  • 1
ivan_pozdeev
  • 33,874
  • 19
  • 107
  • 152