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_listparameter when you calladd_to_shopping_list(), the function uses theNonedefault value forshopping_list. And sinceNoneis falsy, theorexpression 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_listparameter 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_itemsis an empty list.You pass it to
add_to_shopping_list(), soshopping_listnow refers to the same list asclothing_itemswithin the function.It's now the
orexpression's turn within the function,shopping_list = shopping_list or []. But the identifier (name)shopping_listnow refers to the same list thatclothing_itemsrefers to. This is an empty list. Therefore, it's falsy……and since the first operand of the
orexpression is falsy, the expression evaluates to the second operand, which is also an empty list.But—and this is the key point—the
orexpression creates a new empty list rather than using the existing empty list (the one thatclothing_itemsrefers 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.