Flashy, Fancy Shortcuts Aren't Always Suitable [Python Shorts]
A Python Shorts post about a shortcut that's often overused
In the previous post, I talked about Python's or
keyword and how it doesn't behave the way you may expect it to. Here's the link to that article if you missed it: Do You Really Know How `or` And `and` Work in Python?
One place you may see the or
expression used is when dealing with the infamous mutable default value problem in functions–see the second section in Python Quirks? Party Tricks? Peculiarities Revealed… if you're not familiar with this Python banana skin. It seems some LLM models are keen to suggest this option, too.
To keep this post brief, I'll assume you're familiar with both how or
works and the mutable default value issue.
Let's see how the or
keyword is used to solve the mutable default value problem:

I'm using this function for demonstration purposes. Note that the function mutates the list and returns it.
But let's look at the part that's more relevant for this post. This function uses an empty list if no value is passed to the shopping_list
parameter. Since you can't use an empty list as the default value, you use None
as the default value.
The or
expression then does all the hard work:
If you don't pass a list to the
shopping_list
parameter when you calladd_to_shopping_list()
, the function uses theNone
default value forshopping_list
. And sinceNone
is falsy, theor
expression evaluates to its second operand, the empty list[]
.However, if you already have a list with items in it and you pass it to the
shopping_list
parameter when you calladd_to_shopping_list()
, then this list is the one used within the function.
Let's try it out to confirm this is how the function works.
First, try with an existing list:
You create a food_groceries
list containing a few items. You then pass it to add_to_shopping_list()
. You display output
and food_groceries
—these are names referring to the same list. They're not different lists. You can refresh your memory about Python's pass-by-assignment in functions here: If You Haven't Got A Clue What "Pass By Value" or "Pass By Reference" mean, read on…
This is what you expect. Great.
How about using the default value now:
There's no second argument when you call add_to_shopping_list()
this time. Therefore, the function creates an empty list and appends "Washing Up Liquid"
to it.
Again, this is the behaviour you expect.
So, using the or
expression to deal with the mutable default value in functions is cool, right?
Now Consider This…
Have a look at this scenario:
This scenario seems similar to the first one earlier, the one with the food_groceries
. You create a list called clothing_items
and you then pass it to the add_to_shopping_list()
function.
But now, although output
shows the expected result, the list clothing_items
is still empty.
Here's what's happening:
The list
clothing_items
is an empty list.You pass it to
add_to_shopping_list()
, soshopping_list
now refers to the same list asclothing_items
within the function.It's now the
or
expression's turn within the function,shopping_list = shopping_list or []
. But the identifier (name)shopping_list
now refers to the same list thatclothing_items
refers to. This is an empty list. Therefore, it's falsy……and since the first operand of the
or
expression is falsy, the expression evaluates to the second operand, which is also an empty list.But—and this is the key point—the
or
expression creates a new empty list rather than using the existing empty list (the one thatclothing_items
refers to).
So, you still have an empty list within your function, but it's not the same one you're expecting.
That's why output
and clothing_items
are different now. They're different lists. This didn't happen in your first example when you used food_groceries
. In that example, output
and food_groceries
both referred to the same list.
The standard way of solving the mutable default value problem doesn't face this issue:
This textbook approach to the mutable default value issue is less fancy, perhaps, but it works without surprises. It's also more readable, and that's important in Python!
Do you want to try video courses designed and delivered in the same style as these posts? You can get a free trial at The Python Coding Place, and you also get access to a members-only forum.
Photo by Dan Cristian Pădureț: https://www.pexels.com/photo/photo-of-multicolored-abstract-painting-1193743/
Code in this article uses Python 3.13
The code images used in this article are created using Snappify. [Affiliate link]
You can also support this publication by making a one-off contribution of any amount you wish.
For more Python resources, you can also visit Real Python—you may even stumble on one of my own articles or courses there!
Also, are you interested in technical writing? You’d like to make your own writing more narrative, more engaging, more memorable? Have a look at Breaking the Rules.
And you can find out more about me at stephengruppetta.com
Further reading related to this article’s topic:
Appendix: Code Blocks
Code Block #1
def add_to_shopping_list(item, shopping_list=None):
shopping_list = shopping_list or []
shopping_list.append(item)
return shopping_list
Code Block #2
food_groceries = ["Milk", "Eggs", "Bread"]
output = add_to_shopping_list("Chocolate", food_groceries)
output
# ['Milk', 'Eggs', 'Bread', 'Chocolate']
food_groceries
# ['Milk', 'Eggs', 'Bread', 'Chocolate']
Code Block #3
household_items = add_to_shopping_list("Washing Up Liquid")
household_items
# ['Washing Up Liquid']
Code Block #4
clothing_items = []
output = add_to_shopping_list("Shirt", clothing_items)
output
# ['Shirt']
clothing_items
# []
Code Block #5
def add_to_shopping_list(item, shopping_list=None):
if shopping_list is None:
shopping_list = []
shopping_list.append(item)
return shopping_list
clothing_items = []
output = add_to_shopping_list("Shirt", clothing_items)
output
# ['Shirt']
clothing_items
# ['Shirt']
For more Python resources, you can also visit Real Python—you may even stumble on one of my own articles or courses there!
Also, are you interested in technical writing? You’d like to make your own writing more narrative, more engaging, more memorable? Have a look at Breaking the Rules.
And you can find out more about me at stephengruppetta.com
This is a lovely example of those things that can bite you on the backside. Thank you for sharing it.