New assignmens ...

Christman, Roger Graydon dvl at psu.edu
Mon Oct 25 12:47:45 EDT 2021


Message: 8
Date: Mon, 25 Oct 2021 11:20:52 +0200
From: Antoon Pardon <antoon.pardon at vub.be>
To: python-list at python.org
Subject: Re: New assignmens ...
Message-ID: <5761dd65-4e87-8b8c-1400-edb8212048db at vub.be>
Content-Type: text/plain; charset=utf-8; format=flowed
On 25/10/2021 11:20, Anton Pardon wrote:
> Suppose I would like to write a loop as follows:

 >    while ((a, b) := next_couple(a, b))[1]:
 >        do needed calculations


> What I can do is write it as follows:

>     while [tmp := next_couple(a,b), a := tmp[0], b := tmp[1]][-1]:
 >        do needed calculations

> I really don't see what is gained by "forcing" me to right the second code over the first.

No, nobody is forcing you to right it the second way over the first.
Nobody is forcing you to use the walrus operator at all!

Instead, I would recommend something more like:

   while b:
         do needed calculations
         (a,b) = next_couple(a,b)

This requires even less typing than what you had before!

But it also raises a whole lot of problems with this particular example:
-- neither a nor b is defined in your sample while loop.   It seems you would
    need to initialize a and b before your while loop (and mine)
-- is b truly a boolean value, or are you short-cutting some other value?
-- are a and b truly necessary parameters to next_couple, or are they just
    there to remind the function of its previous return values?
    If the latter, poerhaps you want a stream or list or something with yield

This example (and some of the others I have seen) just highlight how
programmers will take advantage of any new tool to help them write
worse code than if they did not have the tool.   In my mind, the walrus
operator was designed to serve a particular niche case like this one:

while (x := input()) > 0:

where not having the operator required duplicating the input() operation
both before the loop and at the end of the loop  -- or more complicated
cases where some additional operations had to be performed to get
that test value for the while condition (such as getting the b out of (a,b)).

But the walrus only adds a benefit if it is there to avoid the duplication
of the code that is used to obtain that test condition.   This next_couple
example does not qualify, since apparently (a,b) are initialized by some
other means (and not be a call to next_couple with undefined values)

Or the other abuse I saw recently about using the walrus operator:

while (self.ctr := self.ctr-1) > 0:

-- there was no compelling reason for a loop counter to be a class variable
(anyone who peeks at this counter when the loop is down would only see a zero)
-- this requires self.ctr to be initialized to a value one higher than the first
meaningful value (start at 11 if you want to count down from 10)
So my recommended alternative, which furthermore also takes less typing:

while ctr > 0:
      ...
      ctr = ctr-1

TL;DR:   The Walrus operator serves the purpose as described in its PEP
just as it is, and I see no compelling reason to expand its use.
It is there to reduce code size by eliminating a duplication of code,
If the code you write using the walrus operator is longer or more
complicated than the code would be without it, you are misusing it.

Roger Christman
Pennsylvania State University


More information about the Python-list mailing list