One of the most commonly asked questions by Python developers is: “Does Python use pass-by-value or pass-by-reference?”
Table of Contents
Does Python use pass-by-value or pass-by-reference?
The answer isn’t as straightforward as it is in languages like C++ or Java. Python follows a “pass-by-object-reference” model, which is sometimes referred to as “pass-by-assignment.”
This article will explore how Python handles function arguments and how the behavior differs for mutable and immutable objects.
What is Pass-by-Value and Pass-by-Reference?
Before diving into Python, let’s first understand these two common parameter-passing mechanisms:
- Pass-by-Value: A copy of the variable is passed to the function. Modifications inside the function do not affect the original variable.
- Pass-by-Reference: A reference (memory address) of the variable is passed to the function. Changes inside the function affect the original object.
Python does not strictly follow either of these. Instead, it passes references to objects. However, the behavior depends on whether the object is mutable or immutable.
Parameter Passing in Python
Immutable Objects (Pass-by-Value-like Behavior)
Immutable objects in Python include:
- Integers (int)
- Floating-point numbers (float)
- Strings (str)
- Tuples (tuple)
- Booleans (bool)
Example For Immutable
x =1
print(id(x)) #4356531368
x = 9
print(id(x)) #4356531624
PythonWhen you pass an immutable object to a function, Python passes a reference to the object. However, since these objects cannot be modified in place, any changes inside the function result in a new object being created rather than modifying the original.
Example: Passing an Integer
def modify(x):
print("Before modification:", x, "ID:", id(x))
x = x + 10 # Creates a new integer object
print("After modification:", x, "ID:", id(x))
num = 5
modify(num)
print("Outside function:", num, "ID:", id(num))
PythonOutput
Before modification: 5 ID: 140704148661776
After modification: 15 ID: 140704148662096
Outside function: 5 ID: 140704148661776
PythonKey Takeaway:
- The num(num =5) variable remains unchanged because integers are immutable.
- So modifying them inside the function creates a new objects, leaving the original unchanged.
Mutable Objects (Pass-by-Reference-like Behavior)
Mutable objects include:
- Lists (list)
- Dictionaries (dict)
- Sets (set)
- Bytearrays (bytearray)
If a function modifies a mutable object in place, the changes will reflect outside the function as well.
Example: Passing a List
def modify_list(lst):
print("Before modification:", lst, "ID:", id(lst))
lst.append(4) # Modifies the same list object
print("After modification:", lst, "ID:", id(lst))
numbers = [1, 2, 3]
modify_list(numbers)
print("Outside function:", numbers, "ID:", id(numbers))
PythonOutput
Before modification: [1, 2, 3] ID: 140315953014976
After modification: [1, 2, 3, 4] ID: 140315953014976
Outside function: [1, 2, 3, 4] ID: 140315953014976
PythonSince lists are mutable, modifications inside the function affect the original list.
Reassigning a Mutable Object Inside a Function
If you reassign a mutable object inside a function, the reference inside the function now points to a new object. However, the original variable outside the function remains unchanged.
Example: Reassigning a List
def modify_list(lst):
print("Before reassignment:", lst, "ID:", id(lst))
lst = [10, 20, 30] # New list assigned
print("After reassignment:", lst, "ID:", id(lst))
numbers = [1, 2, 3]
modify_list(numbers)
print("Outside function:", numbers, "ID:", id(numbers))
PythonOutput
Before reassignment: [1, 2, 3] ID: 140522834077056
After reassignment: [10, 20, 30] ID: 140522834121472
Outside function: [1, 2, 3] ID: 140522834077056
PythonKey Takeaway: Reassigning a new list inside the function does not change the original numbers list.
Avoiding Unwanted Changes: Using .copy()
To avoid modifying the original mutable object, you can pass a copy of the object.
def modify_list(lst):
lst = lst.copy() # Creates a new list
lst.append(99)
print("Inside function:", lst)
numbers = [1, 2, 3]
modify_list(numbers)
print("Outside function:", numbers) # Original list remains unchanged
PythonOutput
Inside function: [1, 2, 3, 99]
Outside function: [1, 2, 3]
PythonSince .copy() creates a new list, modifications inside the function do not affect the original numbers.
Conclusion
In Python, function arguments are passed by object reference, which means that the behavior depends on whether the object is mutable or immutable.
- Immutable objects (int, str, tuple) behave like pass-by-value, since any modification creates a new object rather than altering the original.
- Mutable objects (list, dict, set) behave like pass-by-reference, allowing in-place modifications that affect the original object.
- Reassigning a mutable object inside a function does not change the original variable—it simply binds the local variable to a new object.
If you need to modify a mutable object without affecting the original, use .copy() or deepcopy() for nested structures.
Understanding Python’s parameter-passing model is crucial for writing efficient, bug-free code and avoiding unintended side effects. Next time you pass an object to a function, ask yourself: “Am I modifying it in place, or am I creating a new object?”