Expand your toolkit with this new operator
With the release of Python 3.8, the assignment-expression operator—also known as the walrus operator—was released.
The operator enables the assignment of a value to be passed into an expression. This generally reduces the number of statements by one. For example:
my_list = [1,2,3]count = len(my_list) if count > 3: print(f"Error, {count} is too many items")# when converting to walrus operator...if (count := len(my_list)) > 3: print(f"Error, {count} is too many items")
If you had to do a quick second glance or maybe blinked a few times, you understand the apprehension toward this new operator. It seems to convolute two simple statements for minimal benefit.
Assuming there is a legitimate answer to why this operator was introduced, the natural question then is how is it useful in a real-world scenario?
I’ve found three areas where I have and will continue to adopt the walrus operator. Additionally, each has an ancillary benefit besides saving a single line, which I will share.
While Loops
While loops seem to be the most commonly cited context to implement a walrus operator. The benefit to using a walrus operator here is you consolidate both the expression as well as the modifier in the while statement. I can’t tell you how many times I’ve written an infinite loop because I forgot to add the modifier statement at the end of my while loop.
line = f.readLine()while line: print(line) line = f.readLine()while line := f.readLine(): print(line)
Be careful, though. Using the walrus operator is better suited for what would be a traditional do/while loop since the assignment happens before the expression. See the discrepancy below:
n = 0 while n < 3: print(n) # 0,1,2 n += 1w = 0 while (w := w + 1) < 3: print(w) # 1,2
From my limited experience, I’ve found it most useful in replacing infinite while loops:
while True: p = input("Enter the password: ") if p == "the password": breakwhile (p := input("Enter the password: ")) != "the password": continue
Being able to turn a while loop into nearly a single statement has been great.
List Comprehension
I’ve found the walrus operator quite helpful in optimizing some of my list comprehension statements. The two criteria I look for are 1) the need to filter data and 2) storing the result of a taxing function. First, let’s look at a traditional list-comprehension statement:
scores = [22,54,75,89]valid_scores = [ longFunction(n) for n in scores if longFunction(n) ]
Notice the condition if longFunction(n)
? Notice our longFunction()
is called twice? This is a candidate for the walrus operator.
scores = [22,54,75,89]valid_scores = [ result for n in scores result := longFunction(n) ]
In our optimized code, longFunction()
is only called once, potentially halving the total calls in the comprehension statement.
Working With Returned Data
This has been the most helpful implementation of the walrus operator for me. I frequently work with a mobile-data-collection software called iFormBuilder. Specifically, I am requesting records (rows of data), and in the event my query returns data, I need to process it. Here’s a code block I write on a daily basis:
# look for failed inspections # if there are failed inspections, assign to technicianrecords = api.readFailedRecords() if len(records) > 0: for record in records: api.assignToTechnician(record)
I’ve begun consolidating the reading of the records and the check using duck typing so the block is only executed when the returned list has data:
if records := api.readFailedRecords():
for record in records:
api.assignToTechnician(record)
This refactoring has been the least disruptive in terms of readability — in fact, I’ve found the walrus operator easier to read in this instance. That’s in contrast to the previous two examples where the readability takes a small hit in favor of peace of mind and performance.
Conclusion
The walrus operator is new and controversial, but only time will tell with how it’s received. Have you begun using it in your code?
Source: medium