I was working with a team of data analysts in New York. We were optimizing some Python functions that handled large datasets.
During the review, one of the junior developers asked me: “Does Python use call by value or call by reference?”
This is a common question. I’ve been coding in Python for more than 10 years, and I can tell you, it’s not as easy as in languages like C++ or Java.
In this tutorial, I’ll explain the concept in simple terms. I’ll also show you examples with full code so you can test it yourself.
What Does Python Use?
Python doesn’t strictly use call by value or call by reference.
Instead, Python uses something called call by object reference (also known as call by sharing).
This means:
- When you pass an object to a function, Python passes the reference to that object, not the actual object itself.
- But whether you can change the original object depends on whether it’s mutable (like lists, dictionaries) or immutable (like integers, strings, tuples).
Method 1 – Example with Immutable Objects (Behaves Like Call by Value)
Let’s start with a simple example using integers.
def update_number(x):
print("Inside function before change:", x)
x = x + 10
print("Inside function after change:", x)
num = 50
print("Before function call:", num)
update_number(num)
print("After function call:", num)Output:
Before function call: 50
Inside function before change: 50
Inside function after change: 60
After function call: 50I executed the above example code and added the screenshot below.

Here, the value of num outside the function didn’t change. This happens because integers are immutable in Python. So in this case, it feels like a call by value.
Method 2 – Example with Mutable Objects (Behaves Like Call by Reference)
Now let’s try with a list.
def update_list(mylist):
print("Inside function before change:", mylist)
mylist.append(100)
print("Inside function after change:", mylist)
data = [10, 20, 30]
print("Before function call:", data)
update_list(data)
print("After function call:", data)Output:
Before function call: [10, 20, 30]
Inside function before change: [10, 20, 30]
Inside function after change: [10, 20, 30, 100]
After function call: [10, 20, 30, 100]I executed the above example code and added the screenshot below.

Here, the list data was modified inside the function, and the changes reflected outside as well. This feels like a call by reference.
Method 3 – Reassign a Mutable Object
There’s a twist! If you reassign the object inside the function, it won’t affect the original.
def reset_list(mylist):
print("Inside function before reset:", mylist)
mylist = [0, 0, 0] # Reassigning
print("Inside function after reset:", mylist)
data = [5, 6, 7]
print("Before function call:", data)
reset_list(data)
print("After function call:", data)Output:
Before function call: [5, 6, 7]
Inside function before reset: [5, 6, 7]
Inside function after reset: [0, 0, 0]
After function call: [5, 6, 7]I executed the above example code and added the screenshot below.

Notice that the original list data didn’t change. That’s because reassigning created a new object inside the function.
Method 4 – Example with Dictionaries
Dictionaries are also mutable, so they behave like lists.
def update_dict(my_dict):
print("Inside function before change:", my_dict)
my_dict["status"] = "active"
print("Inside function after change:", my_dict)
user_info = {"name": "John", "city": "Chicago"}
print("Before function call:", user_info)
update_dict(user_info)
print("After function call:", user_info)Output:
Before function call: {'name': 'John', 'city': 'Chicago'}
Inside function before change: {'name': 'John', 'city': 'Chicago'}
Inside function after change: {'name': 'John', 'city': 'Chicago', 'status': 'active'}
After function call: {'name': 'John', 'city': 'Chicago', 'status': 'active'}The dictionary was updated inside the function, and the changes persisted outside.
Conclusion
- Python uses call by object reference.
- Immutable objects (int, str, tuple) behave like call by value.
- Mutable objects (list, dict, set) behave like call by reference, but only if you modify them without reassigning.
- Reassignment inside a function creates a new object and doesn’t affect the original.
When I first started coding in Python, I often got confused by this behavior. Over time, I realized it’s all about understanding mutability.
Once you know whether your object is mutable or immutable, it becomes much easier to predict how functions will behave.
You may read:
- Use the randint() Function in Python
- Use the wait() Function in Python
- Use the find() Function in Python
- Use Exponential Functions in Python

I am Bijay Kumar, a Microsoft MVP in SharePoint. Apart from SharePoint, I started working on Python, Machine learning, and artificial intelligence for the last 5 years. During this time I got expertise in various Python libraries also like Tkinter, Pandas, NumPy, Turtle, Django, Matplotlib, Tensorflow, Scipy, Scikit-Learn, etc… for various clients in the United States, Canada, the United Kingdom, Australia, New Zealand, etc. Check out my profile.