It’s passed by value of reference. So modifications to the object can be seen outside the function, but assigning the variable to a new object does not change anything outside the function.

It’s essentially the same as passing a pointer in C, or a reference type in Java.

The result of the += case is because that operator actually modifies the list in place, so the effect is visible outside the function. lst.append() is also an in-place operation, which explains your last case.

Answer from arshajii on Stack Overflow
🌐
GeeksforGeeks
geeksforgeeks.org › python › pass-by-reference-vs-value-in-python
Pass by reference vs value in Python - GeeksforGeeks
June 3, 2026 - Explanation: List is mutated inside the function and the changes persist outside because both lst and a refer to the same object. In pass-by-value, a copy of the variable is passed, so changes inside the function don't affect the original.
Discussions

python - How to pass a list by reference? - Stack Overflow
You can't explicitly pass a variable by reference in Python, but you can update properties on existing objects. Therefore, what you can do is update values on L3, all of them in your case, so you could do it like this: More on stackoverflow.com
🌐 stackoverflow.com
List being passed by Value vs by Reference, why? | OutSystems
Trying to figure out why a list is being passed by value vs by reference · List Declared in: Library.Interface.WebBlock.ClientAction More on outsystems.com
🌐 outsystems.com
March 1, 2023
list - Arguments are passed by reference or not in Python - Stack Overflow
Does Python pass arguments to functions by reference or by value? I have heard that ints and chars are passed by value, but lists and strings are passed by reference. But when I write- def prepend( More on stackoverflow.com
🌐 stackoverflow.com
python list by value not by reference - Stack Overflow
I think I have little idea why ... lists by reference). My question is "how can I pass it by value so that appending 'b' does't change values in 'a' ?" ... Save this answer. ... Show activity on this post. You cannot pass anything by value in Python. If you want to make a copy of a, you can do so explicitly, as described in the official Python FAQ: ... Sign up to request clarification or add additional ... More on stackoverflow.com
🌐 stackoverflow.com
🌐
LinkedIn
linkedin.com › pulse › understanding-pass-by-value-vs-pass-by-reference-elhousieny-phdᴬᴮᴰ
Understanding Pass-by-Value vs. Pass-by-Reference and Mutable vs. Immutable in Python
August 20, 2023 - The function modifies a copy of `x` inside its scope, leaving the original value unchanged. When dealing with mutable objects, such as lists and dictionaries, Python passes a reference to the object instead of copying its value.
🌐
Real Python
realpython.com › python-pass-by-reference
Pass by Reference in Python: Background and Best Practices – Real Python
March 18, 2026 - Lists and sets are mutable, as are dictionaries and other mapping types. Strings and tuples are not mutable. Attempting to modify an element of an immutable object will raise a TypeError. Python works differently from languages that support passing arguments by reference or by value.
🌐
Robert Heaton
robertheaton.com › 2014 › 02 › 09 › pythons-pass-by-object-reference-as-explained-by-philip-k-dick
Is Python pass-by-reference or pass-by-value? | Robert Heaton
The two most widely known and easy to understand approaches to parameter passing amongst programming languages are pass-by-reference and pass-by-value.
Find elsewhere
🌐
jdhao's digital space
jdhao.github.io › 2022 › 07 › 27 › pass_list_by_value_python
How to Pass List by Value as Parameter in Python · jdhao's digital space
July 26, 2022 - How can we pass the “value” of this list instead of its “reference”? We can use several ways: ... The first four ways only create a shallow copy of the original list. They only work for simple list consisting of immutable types, for example, a list of int. If the list element is a mutable type themselves, they will not work. Only the copy.deepcopy() method can truly create a new list. https://docs.python.org/3/faq/programming.html#why-did-changing-list-y-also-change-list-x
🌐
OutSystems
outsystems.com › forums › discussion › 86208 › list-being-passed-by-value-vs-by-reference-why
List being passed by Value vs by Reference, why? | OutSystems
March 1, 2023 - Trying to figure out why a list is being passed by value vs by reference · List Declared in: Library.Interface.WebBlock.ClientAction
🌐
Medium
medium.com › @devyjoneslocker › understanding-pythons-pass-by-assignment-in-the-backdrop-of-pass-by-value-vs-9f5cc602f943
Python : What is it? Pass by Value or Pass by Reference? It is Pass by Assignment | Medium
June 10, 2023 - This behavior is akin to the “pass-by-value” behavior observed in other programming languages, where a copy of the variable is passed into a function, and any modifications made inside the function do not affect the original variable.
🌐
Mathspp
mathspp.com › blog › pydonts › pass-by-value-reference-and-assignment
Pass-by-value, reference, and assignment | Pydon't 🐍 | mathspp
November 3, 2021 - As we can see, the list l, that was defined outside of the function, changed after calling the function clearly_not_pass_by_value. Hence, Python does not use a pass-by-value model. In a true pass-by-reference model, the called function gets ...
Top answer
1 of 4
2

Python is PASS-BY-VALUE only.

Just like non-primitives in Java, all values in Python are references, i.e. pointers to objects. And just like in Java, they are assigned and passed by value. Always.

My definition is: If simple assignment (=) to a parameter has the same effect as simple assignment (=) to the passed variable in the calling scope, then it is pass-by-reference. If simple assignment (=) to a parameter has no effect on the passed variable in the calling scope, then it is pass-by-value. It is the latter in Java, Python, Ruby, Scheme, Go, C, JavaScript, Smalltalk, and many other languages.

2 of 4
0

list = [element] + list creates a new list and overwrites the original value of, um, list. I doesn't add element to the existing list so it doesn't demonstrate pass by reference. It is equivalent to:

list2 = [element] + list
list = list2

The following demonstrates pass by reference by adding to the existing list instead of creating a new one.

def prepend(element, _list):
    _list.insert(0, element)

_try = [1,2,3]
prepend(0, _try)
print(_try)

UPDATE

It may be more clear if I add print statements that show how the variables change as the program executes. There are two versions of prepend, one that creates a new object and another that updates an existing object. The id() function returns a unique identifier for the object (in cpython, the memory address of the object).

def prepend_1(element, _list):
    print 'prepend_1 creates a new list, assigns it to _list and forgets the original'
    print '_list refers to the same object as _try -->', id(_list), _list
    _list = [element] + _list
    print '_list now refers to a different object -->', id(_list), _list

def prepend_2(element, _list):
    print 'prepend_2 updates the existing list'
    print '_list refers to the same object as _try -->', id(_list), _list
    _list.insert(0, element)
    print '_list still refers to the same object as _try -->', id(_list), _list

_try = [1,2,3]
print '_try is assigned -->', id(_try), _try
prepend_1(0, _try)
print '_try is the same object and is not updated -->', id(_try), _try
prepend_2(0, _try)
print '_try is the same object and is updated -->', id(_try), _try
print _try

When I run it, you can see how the objects relate to the variables that reference them

_try is assigned --> 18234472 [1, 2, 3]
prepend_1 creates a new list, assigns it to _list and forgets the original
_list refers to the same object as _try --> 18234472 [1, 2, 3]
_list now refers to --> 18372440 [0, 1, 2, 3]
_try is the same object and is not updated --> 18234472 [1, 2, 3]
prepend_2 updates the existing list
_list refers to the same object as _try --> 18234472 [1, 2, 3]
_list still refers to the same object as _try --> 18234472 [0, 1, 2, 3]
_try is the same object and is updated --> 18234472 [0, 1, 2, 3]
[0, 1, 2, 3]
🌐
CodingTechRoom
codingtechroom.com › question › are-python-list-objects-passed-by-reference-or-by-value
Are Python List Objects Passed by Reference or By Value? - CodingTechRoom
In Python, all objects are passed by reference, including list objects. This means that when you pass a list to a function, you are passing a reference to that list, not a copy of it. Therefore, modifications made to the list inside the function will affect the original list outside the function.
🌐
Quora
quora.com › How-do-you-pass-lists-by-reference-in-Python-Python-3-x-development
How to pass lists by reference in Python (Python 3.x, development) - Quora
Answer (1 of 2): Python does something called pass-by-assignment, which is different to both pass-by-value and pass-by-reference. This C++ code is pass-by-reference: [code]#include using namespace std; void double_it(int &a) { a += a; } int main(int argc, char **argv) { in...
🌐
Python Guides
pythonguides.com › python-pass-by-reference-or-value
Python Pass By Reference Or Value With Examples
September 6, 2025 - 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.
🌐
FavTutor
favtutor.com › blogs › pass-by-reference-in-python
Pass by Reference in Python | With Examples
October 7, 2023 - In Python, everything is an object, including variables. When you pass a variable to a function, you are effectively passing a reference to the object the variable points to. This behavior holds true for both mutable and immutable objects. def ...
Top answer
1 of 12
224

There are essentially three kinds of 'function calls':

  • Pass by value
  • Pass by reference
  • Pass by object reference

Python is a pass by object reference programming language.

Firstly, it is important to understand that a variable, and the value of the variable (the object) are two separate things. The variable 'points to' the object. The variable is not the object. Again:

THE VARIABLE IS NOT THE OBJECT

Example: in the following line of code:

>>> x = []

[] is the empty list, x is a variable that points to the empty list, but x itself is not the empty list.

Consider the variable (x, in the above case) as a box, and 'the value' of the variable ([]) as the object inside the box.

Pass by object reference (Case in python)

Here, "Object references are passed by value."

def append_one(li):
    li.append(1)
x = [0]
append_one(x)
print x

Here, the statement x = [0] makes a variable x (box) that points towards the object [0].

On the function being called, a new box li is created. The contents of li are the SAME as the contents of the box x. Both the boxes contain the same object. That is, both the variables point to the same object in memory. Hence, any change to the object pointed at by li will also be reflected by the object pointed at by x.

In conclusion, the output of the above program will be:

[0, 1]

Note:

If the variable li is reassigned in the function, then li will point to a separate object in memory. x however, will continue pointing to the same object in memory it was pointing to earlier.

Example:

def append_one(li):
    li = [0, 1]
x = [0]
append_one(x)
print x

The output of the program will be:

[0]

Pass by reference

The box from the calling function is passed on to the called function. Implicitly, the contents of the box (the value of the variable) are passed on to the called function. Hence, any change to the contents of the box in the called function will be reflected in the calling function.

Pass by value

A new box is created in the called function, and copies of contents of the box from the calling function are stored into the new boxes.

2 of 12
89

You can not change an immutable object, like str or tuple, inside a function in Python, but you can do things like:

def foo(y):
  y[0] = y[0]**2

x = [5]
foo(x)
print x[0]  # prints 25

That is a weird way to go about it, however, unless you need to always square certain elements in an array.

Note that in Python, you can also return more than one value, making some of the use cases for pass by reference less important:

def foo(x, y):
   return x**2, y**2

a = 2
b = 3
a, b = foo(a, b)  # a == 4; b == 9

When you return values like that, they are being returned as a Tuple which is in turn unpacked.

edit: Another way to think about this is that, while you can't explicitly pass variables by reference in Python, you can modify the properties of objects that were passed in. In my example (and others) you can modify members of the list that was passed in. You would not, however, be able to reassign the passed in variable entirely. For instance, see the following two pieces of code look like they might do something similar, but end up with different results:

def clear_a(x):
  x = []

def clear_b(x):
  while x: x.pop()

z = [1,2,3]
clear_a(z) # z will not be changed
clear_b(z) # z will be emptied
Top answer
1 of 16
3595

Arguments are passed by assignment. The rationale behind this is twofold:

  1. the parameter passed in is actually a reference to an object (but the reference is passed by value)
  2. some data types are mutable, but others aren't

So:

  • If you pass a mutable object into a method, the method gets a reference to that same object and you can mutate it to your heart's delight, but if you rebind the reference in the method, the outer scope will know nothing about it, and after you're done, the outer reference will still point at the original object.

  • If you pass an immutable object to a method, you still can't rebind the outer reference, and you can't even mutate the object.

To make it even more clear, let's have some examples.

List - a mutable type

Let's try to modify the list that was passed to a method:

def try_to_change_list_contents(the_list):
    print('got', the_list)
    the_list.append('four')
    print('changed to', the_list)

outer_list = ['one', 'two', 'three']

print('before, outer_list =', outer_list)
try_to_change_list_contents(outer_list)
print('after, outer_list =', outer_list)

Output:

before, outer_list = ['one', 'two', 'three']
got ['one', 'two', 'three']
changed to ['one', 'two', 'three', 'four']
after, outer_list = ['one', 'two', 'three', 'four']

Since the parameter passed in is a reference to outer_list, not a copy of it, we can use the mutating list methods to change it and have the changes reflected in the outer scope.

Now let's see what happens when we try to change the reference that was passed in as a parameter:

def try_to_change_list_reference(the_list):
    print('got', the_list)
    the_list = ['and', 'we', 'can', 'not', 'lie']
    print('set to', the_list)

outer_list = ['we', 'like', 'proper', 'English']

print('before, outer_list =', outer_list)
try_to_change_list_reference(outer_list)
print('after, outer_list =', outer_list)

Output:

before, outer_list = ['we', 'like', 'proper', 'English']
got ['we', 'like', 'proper', 'English']
set to ['and', 'we', 'can', 'not', 'lie']
after, outer_list = ['we', 'like', 'proper', 'English']

Since the the_list parameter was passed by value, assigning a new list to it had no effect that the code outside the method could see. The the_list was a copy of the outer_list reference, and we had the_list point to a new list, but there was no way to change where outer_list pointed.

String - an immutable type

It's immutable, so there's nothing we can do to change the contents of the string

Now, let's try to change the reference

def try_to_change_string_reference(the_string):
    print('got', the_string)
    the_string = 'In a kingdom by the sea'
    print('set to', the_string)

outer_string = 'It was many and many a year ago'

print('before, outer_string =', outer_string)
try_to_change_string_reference(outer_string)
print('after, outer_string =', outer_string)

Output:

before, outer_string = It was many and many a year ago
got It was many and many a year ago
set to In a kingdom by the sea
after, outer_string = It was many and many a year ago

Again, since the the_string parameter was passed by value, assigning a new string to it had no effect that the code outside the method could see. The the_string was a copy of the outer_string reference, and we had the_string point to a new string, but there was no way to change where outer_string pointed.

I hope this clears things up a little.

EDIT: It's been noted that this doesn't answer the question that @David originally asked, "Is there something I can do to pass the variable by actual reference?". Let's work on that.

How do we get around this?

As @Andrea's answer shows, you could return the new value. This doesn't change the way things are passed in, but does let you get the information you want back out:

def return_a_whole_new_string(the_string):
    new_string = something_to_do_with_the_old_string(the_string)
    return new_string

# then you could call it like
my_string = return_a_whole_new_string(my_string)

If you really wanted to avoid using a return value, you could create a class to hold your value and pass it into the function or use an existing class, like a list:

def use_a_wrapper_to_simulate_pass_by_reference(stuff_to_change):
    new_string = something_to_do_with_the_old_string(stuff_to_change[0])
    stuff_to_change[0] = new_string

# then you could call it like
wrapper = [my_string]
use_a_wrapper_to_simulate_pass_by_reference(wrapper)

do_something_with(wrapper[0])

Although this seems a little cumbersome.

2 of 16
909

The problem comes from a misunderstanding of what variables are in Python. If you're used to most traditional languages, you have a mental model of what happens in the following sequence:

a = 1
a = 2

You believe that a is a memory location that stores the value 1, then is updated to store the value 2. That's not how things work in Python. Rather, a starts as a reference to an object with the value 1, then gets reassigned as a reference to an object with the value 2. Those two objects may continue to coexist even though a doesn't refer to the first one anymore; in fact they may be shared by any number of other references within the program.

When you call a function with a parameter, a new reference is created that refers to the object passed in. This is separate from the reference that was used in the function call, so there's no way to update that reference and make it refer to a new object. In your example:

def __init__(self):
    self.variable = 'Original'
    self.Change(self.variable)

def Change(self, var):
    var = 'Changed'

self.variable is a reference to the string object 'Original'. When you call Change you create a second reference var to the object. Inside the function you reassign the reference var to a different string object 'Changed', but the reference self.variable is separate and does not change.

The only way around this is to pass a mutable object. Because both references refer to the same object, any changes to the object are reflected in both places.

def __init__(self):         
    self.variable = ['Original']
    self.Change(self.variable)

def Change(self, var):
    var[0] = 'Changed'
🌐
Hacker News
news.ycombinator.com › item
Actually in Python is pass-by-reference with lists and dictionaries. | Hacker News
December 6, 2009 - 1) Variables being references(pointers) to objects · 2) Function arguments being passed by reference or by value