Using the Python walrus operator
<p>
A pattern I often encounter is iterating through a range of values, computing an operation on those values and assigning them to a variable. For example, imagine you are saving files and you don't want to over write them, I create an index and keep increasing it until I get a filename which is available. Something like this:
</p>
<pre class="codehilite"><code class="language-python">filename = 'data_{}.dat'
i = 0
while os.path.exists(filename.format(i)):
i+=1
file = filename.format(i)
data.save(file)
</code></pre>
<p>
<a class="wikilink" href="/python/">
Python
</a>
(I believe 3.8) has introduced a new operator called
<code>
Walrus
</code>
, which greatly simplifies the code above:
</p>
<pre class="codehilite"><code class="language-python">i = 0
filename = 'data_{}.dat'
while os.path.exists(file := filename.format(i)):
i += 1
data.save(file)
</code></pre>
<p>
The
<strong>
walrus
</strong>
operator allows to assign variables to expressions within another expression. In this case, we assigned
<code>
filename.format(i)
</code>
to
<code>
file
</code>
and check its existence.
</p>
<p>
If you want to see a real-world example of when I would use the walrus, check
<a href="https://github.com/aquilesC/experimentor/blob/9d3320694223a1081c69a4081bed3aeb2ae6b2cd/experimentor/models/experiments/base_experiment.py#L222">
this few lines of code
</a>
or
<a href="https://github.com/PFTL/py4lab/blob/393c945c83125f92263d2c30a25a321684519ebc/ch_09/PythonForTheLab/Model/experiment.py#L83">
these ones
</a>
, in which I search for an appropriate filename.
</p>
<p>
<strong>
A caveat
</strong>
: parenthesis play an important role in order resolution:
</p>
<pre class="codehilite"><code class="language-python">var = [1, 2, 3, 4]
if n := len(var) > 3:
print(n)
</code></pre>
<p>
Outputs
<code>
True
</code>
, while:
</p>
<pre class="codehilite"><code class="language-python">var = [1, 2, 3, 4]
if (n := len(var)) > 3:
print(n)
</code></pre>
<p>
Outputs
<code>
4
</code>
. In the example with the filename it was not an issue because I was using already another function with the output of the walrus.
</p>
<p>
I am still hesitant about adding this syntax, since it only works on latest versions of Python which are still not the default on Linux.
</p>
Comment
Share your thoughts on this note. Comments are not public, they are
messages sent directly to my inbox.