Why does Python assignment not return a value?

I believe this was deliberate on Guido's part in order to prevent certain classic errors. E.g.

if x = 3: print x

when you actually meant to say

if x == 3: ...

I do agree there are times I wished it would work, but I also miss { and } around a block of code, and that sure isn't going to change.


The real-world answer: it's not needed.

Most of the cases you see this in C are because of the fact that error handling is done manually:

if((fd = open("file", O_RDONLY)) == -1)
{
    // error handling
}

Similarly for the way many loops are written:

while(i++ < 10)
    ;

These common cases are done differently in Python. Error handling typically uses exception handling; loops typically use iterators.

The arguments against it aren't necessarily earth-shattering, but they're weighed against the fact that it simply isn't that important in Python.


Assignment (sub-)expressions (x := y) are supported since Python 3.8 (released Oct. 2019), so you can indeed now rewrite your example as lst.append(x := X()).

The proposal, PEP 572, was formally accepted by Guido in July 2018. There had also been earlier proposals for assignment expressions, such as the withdrawn PEP 379.

Recall that until version 3, print was also a statement rather than an expression.

The statement x = y = z to assign the same value to multiple targets (or rather, multiple target-lists, since unpacking is also permitted) was already supported (e.g. since version 1) but is implemented as a special syntax rather than by chaining successive assignment sub-expressions. Indeed, the order in which the individual assignments are performed is reversed: nested walruses (x := (y := z)) must assign to y before x, whereas x = y = z assigns to x before y (which may be pertinent if you set/assign to the subscripts or attributes of a class that has been overloaded to create some side-effect).


There are many who feel that having assignments be expressions, especially in languages like Python where any value is allowable in a condition (not just values of some boolean type), is error-prone. Presumably Guido is/was among those who feel that way. The classic error is:

if x = y: # oops! meant to say ==

The situation is also a bit more complicated in Python than it is in a language like C, since in Python the first assignment to a variable is also its declaration. For example:

def f():
    print x

def g():
    x = h()
    print x

In these two functions the "print x" lines do different things: one refers to the global variable x, and the other refers to the local variable x. The x in g is local because of the assignment. This could be even more confusing (than it already is) if it was possible to bury the assignment inside some larger expression/statement.