tags:

views:

180

answers:

5

Hi,

Is it possible to have assignment in a condition?

For ex.

if (a=some_func()):
    # Use a
+11  A: 

Why not try it out?

>>> def some_func():
...   return 2
... 
>>> a = 2
>>> if (a = some_func()):
  File "<stdin>", line 1
    if (a = some_func()):
          ^
SyntaxError: invalid syntax
>>> 

So, no.

Jason Hall
this is intentionally forbidden as Guido, benevolent python dictator, finds them unnecessary and more confusing than useful. It's the same reason there's no post-increment or pre-increment operators (++).
Matt Boehm
he did allow the addition of *augmented assigment* in 2.0 because `x = x + 1` requires additional lookup time while `x += 1` was somewhat faster, but i'm sure he didn't even like doing *that* much. :-)
wescpy
+2  A: 

No. Assignment in Python is a statement, not an expression.

Ignacio Vazquez-Abrams
And Guido wouldn't have it any other way.
Mark Ransom
+3  A: 

http://docs.python.org/tutorial/datastructures.html

Note that in Python, unlike C, assignment cannot occur inside expressions. C programmers may grumble about this, but it avoids a common class of problems encountered in C programs: typing = in an expression when == was intended.

also see:

http://effbot.org/pyfaq/why-can-t-i-use-an-assignment-in-an-expression.htm

gnibbler
+8  A: 

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.

Kevin Little
+1  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
Alex Martelli