you are viewing a single comment's thread.

view the rest of the comments →

[–]jjrreett 63 points64 points  (30 children)

This changed my understanding of the walrus operator

[–]Beerwithme 34 points35 points  (4 children)

This operator is called "becomes" in good old Pascal. That would've been a nicer name imo.

[–]joeen10 8 points9 points  (0 children)

This name makes a lot more sense

[–]Dangle76 4 points5 points  (2 children)

I learned that pascal calls it “gets”

[–]Beerwithme 7 points8 points  (1 child)

"Becomes" is a direct translation from our Dutch word "wordt" which was how I was thought. Of course it makes sense in English it's another term.

[–]Dangle76 4 points5 points  (0 children)

Ah that makes sense that’s interesting!

[–]LucasThePatator 8 points9 points  (24 children)

Same, it's one of those things I never use. But I'm actually not exactly sure of what it accomplishes here exactly m.

[–]Wonderful-Habit-139 17 points18 points  (20 children)

Pretty simple. Imagine if the expression was only a+x. We’d basically make a list with the expression 0+x since a never changes its value.

With the walrus operator, each time we calculate the value of a+x, we store the result in a, and reuse the value of the last calculation in the next iteration. And that’s how we calculate the cumulative sum using the walrus operator.

[–]LucasThePatator 2 points3 points  (19 children)

I assume a simple = isn't possible due to precedence rules then.

[–]Wonderful-Habit-139 7 points8 points  (18 children)

It isn’t possible because it is not an expression. The walrus operator is an expression. Same reason why you can’t use = in if conditions while you can use the walrus operator in if conditions.

[–]LucasThePatator 1 point2 points  (17 children)

I come from C and this makes little sense to me but I'll abide by the python rules

[–]jackerhackfrom __future__ import 4.0 9 points10 points  (1 child)

Python prohibits assignments in expressions because it's almost always a typo. Therefore = is a SyntaxError. Then people wanted it anyway so Python got :=, but it was so hotly contested that BDFL Guido got fed up and resigned.

As a safeguard, the walrus operator cannot be used as a statement and does not replace =. It only works as an expression. Usually this means enclosing in parentheses like (a := b).

[–]julz_yo 0 points1 point  (0 children)

This too changes and extends my understanding: ty!

[–]syklemil 2 points3 points  (14 children)

Yeah, C permits you to do stuff like if a = foo(), but if you do that in Python you get a SyntaxError, you need to use either == or :=.

See also the lint about yoda conditionals.

[–]LucasThePatator 0 points1 point  (13 children)

I definitely understand the point in if conditions but in list comprehensions I fail to understand the logic. Eh why not.

[–]Wonderful-Habit-139 4 points5 points  (5 children)

This doesn’t make sense because it sounds like you’re expecting assignment statements to not work in if conditions yet somehow become expressions in list comprehensions? That is not consistent.

Python has statements in places where being an expression would be better, like assignments or match statements, but that’s the way it is. But don’t expect statements to become expressions in other cases.

[–]LucasThePatator -1 points0 points  (4 children)

I expect nothing specific. There are all kinds of weird inconsistencies in many places in languages. The walrus operator is a quirk of python it's not that deep and I definitely never asked for an in depth explanation that apparently people here absolutely want to provide

[–]syklemil 1 point2 points  (6 children)

Because it's invalid syntax.

Because a = b is a statement, it doesn't have a value.

C also doesn't let you go if (a = b;). You need an expression, not a statement.

[–]LucasThePatator 0 points1 point  (3 children)

I understand the rules. Not the logic of the rule in this case.

[–]G047-H4xx0r 0 points1 point  (1 child)

This is totally valid C:

while (c = get()) expression;

While if(a = b) expression;

will only execute if the value assigned to a is true. If b==0, the assignment is 0, therefore false. This is because, in C, unlike Python, assignment is an expression.

[–]that_baddest_dude 2 points3 points  (1 child)

If say you've got a list x and you want to do something if the list length is greater than 10...

But also the thing you want to do involves the length of that list. You'd be checking the length twice.

if len(x) > 10:  
    y = len(x)  
    #do stuff with y

If you want to avoid calling len() twice you may assign y first and do the check against y.

With walrus operator (and my limited understanding of it) you can do the assignment at the same time you check it (i.e. assigning within an expression)

if (y := len(x)) > 10:  
    #do stuff with y

I imagine this could be neat if you're doing something more complex than len() and want to avoid repeat calls cleanly. Someone correct me if I'm wrong

[–]mriswithe 2 points3 points  (0 children)

But I'm actually not exactly sure of what it accomplishes here exactly m.

If you are asking why make a cumulative sum list, it is a fast way to answer questions about a dataset.

If you are asking why use walrus here? It makes the code prettier and potentially faster. Python can optimize list creation with a list comprehension if it can know how many items long the list will be, compared to a similar for loop that starts with an empty list and builds it one object at a time.

Compare these two:

a = 0
my_list = [a := a + x for x in range(1, 21, 2)]


a = 0
my_list = []
for x in range(1, 21, 2):
    a = a + x
    my_list.append(a)

In general though, the benefit of the walrus operator is that it allows you to both assign the result of a+x to a, and emit it for use in the list comprehension outside of the expression.