Mutable Default Arguments
As we continue our look at places outside of a Boolean context where we can use the
or operator, we’re now going to take a look at how the
or operator can help us when we’re trying to write a function whose intent is to modify the argument value it’s given while at the same time providing a default value for that argument.
Here’s an illustrative example, perhaps not practical, but we’re just trying to get a sense for what the problem is and what the solution is. So, the intent of this
mutable_default() is to append
1 to the end of the list that it’s provided, and if we’re not provided a list at all, create a new list and have
1 added to it.
00:49 This looks like it should work.
And so here’s our
Let’s go ahead and import this. We’ll call this
python_or_da1 (default argument 1).
And we can see that it’s printed out that list, but more importantly, also that list has been changed. Now, if I call
mutable_default() without a parameter, we should expect a new list to be created with
1 appended to it.
01:42 And that looks good—until we try it again.
What’s happened is that same default parameter value—when we look at it here—this name
lst was created when I imported this function, and so every time we call this without a parameter, it’s going back and grabbing this list that was already created.
It was empty at the beginning, and then we added
1 to it. And then as we saw, we just appended
1 to it again. And I can continue this, and that’s not the effect that we want.
02:25 We want each time when we don’t provide it a parameter a new list to be created. What happened here is what we want to happen every time.
So, let’s take a look at a possible solution. Instead of creating an empty list, let’s just create the variable and say that it’s going to be equal to
None if no list is provided.
I have that here in
python_or_da2, and I’m going to call this
mutable_default2() just so we don’t get all of our
mutable_default() functions confused.
So now I’m going to import everything from
my_list already has
1, so if I call
my_list, it appended a
1 to it again.
We’re can see it just didn’t print out that. It’s actually been changed. And now if I don’t provide a parameter, the default one,
lst, will be used.
Let’s take a closer look at this. Because each time we either use
lst or an empty list, if no parameter was provided,
None, which evaluates to
So when the
or encounters the left operand to be
False, we use the right operand, which gives us an empty list. So each time we call this with an empty set of parentheses to use the default value,
lst is assigned to
False, and so then we reassign it to be an empty list.
Now, there’s still a catch, and this is a possibility that perhaps using the
or might not be the best solution. I mentioned that before. So, suppose that I create a new list, but I don’t have anything in it yet, and so I want to call
my_new_list. Well, it looks like things worked but, in fact, they didn’t.
my_new_list wasn’t changed, and the reason it wasn’t changed was because
lst had the parameter
my_new_list was empty, and so this evaluated to be
False, and so a new empty list was created.
05:20 And so if there’s a possibility that the parameter supplied—the meaningful parameter supplied—is going to be an empty list, this solution isn’t going to work.
In fact, you’re probably not going to be able to use an
or statement at all. You want to explicitly check to see if the list is an empty list or if it’s
None, because if it’s
None, then you know a parameter wasn’t provided, but if it’s not
None, then it’s a meaningful list that you can append to.
So, as mentioned before, sometimes
or isn’t the best way to implement the solution to a problem but in many situations it can be and it’s important to know, if you’re going to use it, how to use it correctly.
06:17 In your next lesson, we’re going to see how it can help us prevent getting a division by zero error when we’re trying to do arithmetic.
Become a Member to join the conversation.