Locked learning resources

Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Locked learning resources

This lesson is for members only. Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Recognizing Unsuitable Default Data Types

For more information on concepts covered in this lesson, you can check out Immutability in Python.

00:00 Data Types That Shouldn’t Be Used as Default Arguments. You’ve used integers and strings as default values in the examples seen previously, and None is another common default value.

00:13 These are not the only data types you can use as default values. However, not all types should be used. In this section, you’ll see why mutable data types should not be used as default values in function definitions.

00:28 A mutable object is one whose values can be changed, such as a list or dictionary. You can find out more about mutable and immutable data types in this Real Python course.

00:42 You can add the dictionary containing the item names and quantities as an input parameter to the function you defined earlier. You can start by making all arguments required.

01:03 You can now pass shopping_list to the function when you call it. This makes the function more self-contained, as it doesn’t rely on a variable called shopping_list to exist in the scope that’s calling the function. This change also makes the function more flexible, as you can use it with different input dictionaries.

01:21 You’ve also added the return statement to return this modified dictionary. This line is technically not required at this stage, as dictionaries are a mutable data type, and therefore the function will change the state of the dictionary that exists in the main module. However, you’ll need the return statement later when you make this argument optional, so it’s best to include it now. To call the function, you’ll need to assign the data returned by the function to a variable.

01:51 You can also add a shopping_list parameter to show_list(), the first function you defined in this course. You can now have several shopping lists in your program and use the same functions to add items and display these shopping lists.

02:18 There are three items added to the hardware store list

02:39 and two added to the supermarket list.

02:57 When you run the code, you should see the output as seen on-screen.

03:05 The list of items to buy from the hardware store is shown first. The second part of the output shows the items needed from the supermarket. You’ll now add a default value for the parameter shopping_list in add_item() so that if no dictionary is passed to the function, then an empty dictionary is used.

03:24 The most tempting option is to make the default value an empty dictionary ({}). And you’ll see why this isn’t a good idea soon, but you can try it for now.

03:46 When you run this script, you’ll get the output seen on-screen, showing the items needed from the clothes shop, which may give the impression that this code works as intended. However, this code has a serious flaw that can lead to unexpected and incorrect results.

04:02 You can add a new shopping list for items needed from the electronics store by using add_item() with no argument corresponding to shopping_list.

04:15 This leads to the default value being used, which you’d hope would create a newly empty dictionary. You can see the problem on-screen where you see the output from this code.

04:27 Both shopping lists are identical even though you assigned the output from add_item() to different variables each time you called the function.

04:36 This problem happens because dictionaries are a mutable data type. You assigned an empty dictionary as the default value for the parameter shopping_list when you defined the function. The first time you call the function, this dictionary is empty. However, as dictionaries are a mutable type, when you assign values to the dictionary, the default dictionary is no longer empty. When you call the function the second time, and the default value for shopping_list is required again, the default dictionary is no longer empty, as it was populated the first time you called the function. Since you’re calling the same function, you’re using the same default dictionary that’s stored in memory.

05:16 This behavior doesn’t happen with immutable data types. The solution to this problem is to use another default value, such as None, and then create an empty dictionary within the function when no optional argument is passed.

05:43 You can check whether a dictionary has been passed as an argument using the if statement. You shouldn’t rely on the falsy nature of None, but instead explicitly check that the argument is None. Relying on the fact that None will be treated as a false value can cause problems if another argument that is falsy is passed. Now, when you run your script again, you’ll get the correct output since a new dictionary is created each time you use the function with the default value for shopping_list.

06:14 The takeaway from this is that you should always avoid using a mutable data type as a default value when defining a function with optional parameters. In the next section of the course, you’ll take a look at error messages related to input arguments.

Avatar image for Suan Khuptong

Suan Khuptong on July 3, 2026

In non-used_default.py, there is no global variable called shopping_list but the same dictionary is used to iterate inside the show_list() function. So, when I followed what was written, I get the output as None. Can you please clarify since your code is working and mine isn’t?

Avatar image for Bartosz Zaczyński

Bartosz Zaczyński RP Team on July 5, 2026

@Suan Khuptong The key thing is that shopping_list in show_list() is a parameter, not a global variable. It’s a local name that receives whatever dictionary you hand the function when you call it, so it doesn’t need a shopping_list to exist outside the function at all.

That’s actually the point this lesson is making. Earlier in the course, show_list() read a global shopping_list directly. Here it has been rewritten to take the dictionary as an argument, which makes it self-contained and lets you reuse it for different lists. This is covered around the 1:07 mark. So when the script calls show_list(clothes_shop_list), the clothes_shop_list dictionary becomes shopping_list inside the function, and .items() iterates over that.

As for the None, my guess is that you wrapped the call in a print(), something like:

print(show_list(clothes_shop_list))

show_list() does its own printing inside the function and doesn’t return anything, so its return value is None. Wrapping it in print() then adds a None line after the items. Calling it directly fixes it:

show_list(clothes_shop_list)

That should print the items with no stray None.

If that is not what happened, paste the exact code you ran (especially the last few lines where you call the functions) and I will take another look. It is easy to misread which version of these functions is which, since the course builds them up step by step.

Become a Member to join the conversation.