python can't to - Can we have assignment in a condition?

3 Answers

Nope, the BDFL didn't like that feature.

From where I sit, Guido van Rossum, "Benevolent Dictator For Life”, has fought hard to keep Python as simple as it can be. We can quibble with some of the decisions he's made -- I'd have preferred he said 'No' more often. But the fact that there hasn't been a committee designing Python, but instead a trusted "advisory board", based largely on merit, filtering through one designer's sensibilities, has produced one hell of a nice language, IMHO.

conditional expression inline

Is it possible to have assignment in a condition?

For ex.

if (a=some_func()):
    # Use a

Not directly, per this old recipe of mine -- but as the recipe says it's easy to build the semantic equivalent, e.g. if you need to transliterate directly from a C-coded reference algorithm (before refactoring to more-idiomatic Python, of course;-). I.e.:

class DataHolder(object):
    def __init__(self, value=None): self.value = value
    def set(self, value): self.value = value; return value
    def get(self): return self.value

data = DataHolder()

while data.set(somefunc()):
  a = data.get()
  # use a

BTW, a very idiomatic Pythonic form for your specific case, if you know exactly what falsish value somefunc may return when it does return a falsish value (e.g. 0), is

for a in iter(somefunc, 0):
  # use a

so in this specific case the refactoring would be pretty easy;-).

If the return could be any kind of falsish value (0, None, '', ...), one possibility is:

import itertools

for a in itertools.takewhile(lambda x: x, iter(somefunc, object())):
    # use a

but you might prefer a simple custom generator:

def getwhile(func, *a, **k):
    while True:
      x = func(*a, **k)
      if not x: break
      yield x

for a in getwhile(somefunc):
    # use a

One of the reasons why assignments are illegal in conditions is that it's easier to make a mistake and assign True or False:

some_variable = 5

# This does not work
# if True = some_variable:
#   do_something()

# This only works in Python 2.x
True = some_variable

print True  # returns 5

In Python 3 True and False are keywords, so no risk anymore.