[Python-Dev] PEP 572: Assignment Expressions

Tim Peters tim.peters at gmail.com
Tue Apr 17 21:35:35 EDT 2018


[Guido, makes peace with `identifier := expression`]
> ...
> I am fine with this, it certainly seems the easiest to implement, with the
> fewest corner cases, and the easiest restriction to explain.
>
> (I was thinking there would be a use case for basic tuple unpacking, like
> seen a lot in for-loop, but the only examples I tried to come up with were
> pretty sub-optimal, so I don't worry about that any more.)

Chris's pain threshold appears to be higher than ours ;-)

So I would really like to see if anyone has plausibly realistic uses
for fancier forms of assignment expression.

I have plenty of code that does stuff like this:

    while True:
        x, y = func_returning_tuple()
        if y is None:
            break
        ...

Maybe it's just that I'm used to it, but I find that very easy to
understand now.  If we had fancy assignment expressions, my first
thought was I could write it like so instead:

    while ((x, y) := func_returning_tuple()) and y is not None:
        ...

and pray that I put in enough parens to get the intended meaning.

And maybe it's just that I'm _not_ used to that, but I do find it
harder to understand.  Contributing factor:  I don't really want "and"
there - what the context requires is really more like C's comma
operator (take only the last value from a sequence of expressions).
As is, I'm relying on that a 2-tuple is truthy regardless of its
content (so that `and` always goes on to evaluate its RHS).

And, for some reason, I find this even worse:

    while ((x, y) := func_returning_tuple())[1] is not None:
        ...

The rub there:  I gave `y` a name but can't use it in the test?!


And those are the same kinds of headaches I saw over & over in my own
"fancier" code:  stuff that's already perfectly clear would become
more obscure instead.

Tuple unpacking works great in for-loops because the only effect there
is to give names to the tuple components, none of which are needed
_in_ the `for` statement itself.  But in a `while" or `if` statement,
I would typically _also_ want to use the names _in_ the `while` or
`if` tests.  But, as in C, that's what the comma operator is for, not
the assignment operator.

    while (s = function_returning_struct_with_x_and_y_members(), s.y != NULL) {
        ...
    }

In contrast, ,many plausible uses I saw for `identifier := expression`
in a `while` or `if` statement would have been improvements, and most
of the rest neutral:  I'm still wondering whether this one is better
or worse ;-):

    def newton(f, fprime, x):
        import math
        while not math.isclose((next_x := x - f(x) / fprime(x)), x):
            x = next_x
        return next_x


More information about the Python-Dev mailing list