0

Valid code:

x, y, z = 1, 2, 3
print(x := x + y)
print(x, y, z)

Invalid code:

arr = [1, 2, 3]
print(arr[0] := arr[0] + arr[1])
print(arr)

Error:

SyntaxError: cannot use assignment expressions with subscript

Another example in which it would be useful:

bool_index = # Problem cells in the array
assert not any(bool_index), "Problems here: \n{}".format(np.full(arr.shape, ".")[bool_index] := "X")

The above snippet would ideally look something like this:

Problems here:
array([['.', '.', '.', '.', '.', '.', '.', '.', '.'],
       ['.', '.', '.', '.', '.', '.', '.', '.', '.'],
       ['.', '.', '.', '.', '.', '.', '.', '.', '.'],
       ['.', '.', '.', '.', '.', '.', '.', '.', '.'],
       ['.', '.', '.', 'X', '.', '.', '.', '.', '.'],
       ['.', '.', '.', '.', '.', '.', '.', '.', '.'],
       ['.', '.', '.', '.', '.', '.', '.', '.', '.'],
       ['.', '.', '.', '.', '.', '.', '.', '.', '.'],
       ['.', '.', '.', '.', '.', '.', '.', '.', '.']], dtype='<U1')

However, we would have to generate that array in a variable ahead of time to mark the "X" (even if we would never show it) or we would have to dedicate additional lines to adding a function which only runs if called by the assert (the function being at least three lines due to still requiring a variable).

I understand the most recent example I gave may be bad style, but small little would-be one-liners of this sort are fairly common in research code and things that would normally fit nicely into a list-comprehension must be instead written in a for-loop due to being unable to write these sorts of expressions.

Does this limitation of the Walrus Operator exist due to any limitation in parsing the language? Was the implementation decided against? Or is this functionality coming in some future version of python? What is the reason for this limitation?

Axoren
  • 522
  • 1
  • 6
  • 22
  • 3
    Says so in the [PEP](https://www.python.org/dev/peps/pep-0572/#differences-between-assignment-expressions-and-assignment-statements) – khelwood May 06 '21 at 19:39
  • @khelwood Cool, it's not supported. I know this. *Why isn't it?* and *Is there a good reason?* – Axoren May 06 '21 at 19:41
  • Unless I'm missing something, I don't see those two questions answered in the PEP – Axoren May 06 '21 at 19:42
  • This is not a technical "why" question. I know the grammar of the language does not support it. This seems like something easily implementable. Was it excluded for a reason other than "Because they said so"? The linked question in the close DOES NOT ADDRESS THIS. – Axoren May 06 '21 at 19:46
  • 2
    Some more explanation [here](https://mail.python.org/pipermail/python-dev/2018-July/154628.html) – khelwood May 06 '21 at 19:47
  • @khelwood If this question weren't closed by someone's poor reading comprehension, I would accept your comment as an answer. – Axoren May 06 '21 at 19:51
  • 1
    There is now an answer at the linked question in the close that satisfies my ask. This question can remain closed. – Axoren May 06 '21 at 19:57
  • `arr[idx]=value` is implemented as `arr.__setitem__(idx, value)`, where `setitem` is usually implemented in class compiled code (such as for list and numpy arrays). I don't have a new enough python to use the walrus operator yet, but I think it would require modifying the method call to return the `arr` object, rather than `None`. – hpaulj May 06 '21 at 20:07
  • 1
    @hpaulj I don't think it would. It would require the interpreter to call `arr.__setitem__(idx, value)` and have the expression itself evaluate to `value`. It wouldn't need `__setitem__` to return anything. – khelwood May 06 '21 at 20:10
  • 1
    @khelwood, I had the impression that the OP wants the walrus operator to return the whole modified array, not just the new value that's added to it. He's trying to avoid generating the `np.full(...)` array, unless it's needed for the assert message. That kind of ambiguity might be reason enough to not support this. – hpaulj May 06 '21 at 20:19
  • @hpaulj I guess that was my intention, and I see now that I would have been using the walrus operator in correctly in that case mentioned. What I really wanted was something of a "builder"-type expression which would return the LHS instead of the RHS after the fact. – Axoren May 06 '21 at 20:23

0 Answers0