This is one aspect of Python that may not be straightforward, particularly for beginners. When passing a parameter to a function, is it passed by value (a copy of the variable) or by reference (a pointer/reference to the variable)?
It depends on the variable type
We have 2 main types of variables in Python, mutable
and immutable
.
Mutable variables, such as lists, dictionaries, and sets, can have their content altered without the need for re-initialization.
Immutable variables, including tuples, strings, and integers, are not designed to have their content changed without re-initialization, which involves creating a new variable.
Let me show you what I mean by a simple example
>>> x = 5
>>> id(x)
4323140904
>>> x += 1
>>> id(x)
4323140936
>>> #You can see how the id of the variable x has changed
>>> l = [1]
>>> id(l)
4308117184
>>> l.append(2)
>>> id(l)
4308117184
>>> #while appending new values to the list, it still maintains the same id
>>> l = [1, 2]
>>> id(l)
4308119552
>>> # But after re-initializing it, it changes
How does that work when passing as arguments?
When you pass a variable to a function, it takes into consideration the type of this variable, and from here it behaves accordingly
Example: Passing an immutable variable to a function
>>> x = 1
>>> def add_2(a):
... print(f"id(a):{id(a)}")
... a +=2
... print(f"id(a):{id(a)}")
... print(a)
...
>>> id(x)
4323140776
>>> add_2(x)
id(a):4323140776
id(a):4323140840
3
>>> x
1
As you can see in the previous example, the id
of the argument a
was the same as x
before we changed its value, but it changed after! and the value of x
hasn't changed!
Example: Passing a mutable variable to a function
>>> def append_2(a):
... print(f"id(a):{id(a)}")
... a.append(2)
... print(f"id(a):{id(a)}")
... print(a)
>>> ls = [1]
>>> append_2(ls)
id(a):4308118656
id(a):4308118656
[1, 2]
>>> id(ls)
4308118656
>>> ls
[1, 2]
As you can notice here, things are different a little bit!
The reference to the list didn't change even after appending a new value to the list, and the append
operation reflected on the original ls
list!