Open In App

Use mutable default value as an argument in Python

Last Updated : 05 Jun, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Python lets you set default values ​​for its parameters when you define a function or method. If no argument for this parameter is passed to the function while calling it in such situations default value will be used. If the default values ​​are mutable or modifiable (lists, dictionaries, etc.), they can be modified within the function and those modifications will persist across function calls.

However, using mutable default values ​​as arguments in Python can lead to unexpected behavior. This article explores the concept of volatile defaults, the potential problems they can cause, and how to use them effectively.

Understanding Mutable and Immutable Values in Python

Before going into the topic, let us get an overview of what mutable and immutable objects are from the perspective of Python.

Mutable Value in Python

Mutable values are the values that can be modified after being created. This implies that you can modify the values without producing a new value. Below is an illustration of mutable and immutable values implemented in Python.

Example:

Python3




# Python mutable value (List)
demo_list = [1, 2, 3, 4, 5]
print("Original List:", demo_list)
  
demo_list[0] = 10
print("Modified List:", demo_list)


Output:

Original List: [1, 2, 3, 4, 5]
Modified List: [10, 2, 3, 4, 5]

Immutable Value in Python

Contrary to mutable values in Python, there is an immutable value that cannot be edited or modified as shown below:

Example:

Python3




# Python immutable values (Tuple)
demo_tuple = (1, 2, 3, 4, 5)
print("Original Tuple", demo_tuple)
  
demo_tuple[0] = 10
print("Modified Tuple", demo_tuple)


Output:

 

What are Mutable Default Values

Now that we know what a mutable value is in Python and when we use such mutable values as default values for parameters when defining a function in Python it is called a mutable default value.

Example:

Python3




# Python function with mutable default value
  
def append_to(element, arr=[]):
    arr.append(element)
    return arr
  
# calling the function
print(append_to(12))
  
print(append_to(42))
  
print(append_to(99))


Output:

As you can see, the above function takes in 2 parameters first `element` value which is a compulsory argument, and the second one `arr` with a default value of an empty list. If we call this function by passing only a single argument means no argument for `arr`, it will use the default value that is an empty list.

[12]
[12, 42]
[12, 42, 99]

As you can see the same list is used whenever we call the function with a single argument, this is because the default value list is modified each time the function is called.

Problems of Using Mutable Default Values

Mutable default values are quite a useful feature provided in Python but they can cause unexpected behavior if not used carefully. Consider the case of the above example where we ended up appending all values to a single list when the function was called only with a single argument.

Now consider calling the function again with both the 2 expected arguments.

Example:

Python3




# Python function with mutable default value
  
def append_to(element, arr=[]):
    arr.append(element)
    return arr
  
# calling the function
print(append_to(12))
  
print(append_to(42))
  
print(append_to(99))
  
# calling the function with two arguments
print(append_to(101, [1, 2, 3]))


Output:

[12]
[12, 42]      
[12, 42, 99]  
[1, 2, 3, 101]

The above output is expected by the function definition. It seems the function is working correctly. However, let’s call the function one more time without passing `arr` to it and see the output.

Example:

Python3




# Python function with mutable default value
  
def append_to(element, arr=[]):
    arr.append(element)
    return arr
  
# calling the function with one argument
print(append_to(12))
  
print(append_to(42))
  
print(append_to(99))
  
# calling the function with two arguments
print(append_to(101, [1, 2, 3]))
  
# unexpected output
print(append_to(102))


Output:

In this example, there is something very important to notice in the last function call output. Instead of creating a new empty list as expected due to the default value in the function definition, it continues to append the values in the previous list. 

[12]
[12, 42]
[12, 42, 99]
[1, 2, 3, 101]
[12, 42, 99, 102]

This behavior is unexpected and can lead to bugs that are difficult to find and debug.

Recommended Way to Use Mutable Default Value

In the above section, we have explained the problems with the above approach now let’s see the recommended method to use a mutable default value to avoid mentioned problems. Following is the modified code in which we used recommended way to use the mutable default value.

Example:

Python3




# recommended way to use mutable default values in Python
def append_to(element, arr=None):
    if arr is None:
        arr = []
    arr.append(element)
    return arr
  
# calling the function with one argument
print(append_to(12))
print(append_to(42))
print(append_to(99))
  
# calling the function with two arguments
print(append_to(101, [1, 2, 3]))
  
# calling the function with one argument again
print(append_to(102))


Output:

In the above code, we have used ‘None’ as the default value instead of an empty list. With this modification, calling the `append_to` function without passing a value for `arr` will always create a new empty list and append the element value into that newly created list. 

[12]
[42]
[99]
[1, 2, 3, 101]
[102]


Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads