That’s an especially obfuscated example of how to create a temporary
variable inside a list comprehension, before the walrus operator.
If you want to do a running sum, you might do this:
data = [1, 2, 3, 4]
sums = []
total = 0
for value in data:
total = total + value
sums.append(total)
How can we write that as a list comprehension? Without using the walrus
operator. Here’s one attempt:
sums = [total for value in data]
but that doesn’t work because total has no value. We can initialise it
from the outside:
total = 0
sums = [total for value in data]
but we’re using two statements instead of a single comprehension, and
the total never gets updated into a running sum. How do we push the
initialisation into the comprehension? By turning it into a loop:
data = [1, 2, 3, 4]
sums = []
for total in [0]:
for value in data:
total = total + value
sums.append(total)
That corresponds to this comprehension:
sums = [total for total in [0] for value in data]
Good news from the What’s New: that loop for total in [0]
inside a
comprehension is now as efficient as a regular assignment total = 0
.
Okay, so now we got our initial value inside the comprehension. But the
total is not being updated into a running sum, it’s always 0. How can we
do that, using only for-loops?
data = [1, 2, 3, 4]
sums = []
for total in [0]:
for value in data:
for total in [total + value]:
sums.append(total)
which gives us this comprehension:
sums = [total for total in [0] for value in data for total in [total + value]]
Obfuscate the names:
# s = total (running sum)
# x = value
sums = [s for s in [0] for x in data for s in [s + x]]
and we’re done.
With the walrus operator, we can use the less obfuscated:
data = [1, 2, 3, 4]
total = 0
sums = [total:=(total + value) for value in data]
although it has the side-effect of updating the value of total.