Class 12:Mutable/Immutable properties

Mutable/Immutable properties of passed data objects

Arguments are always passed to functions by reference in Python.

The main body of the python code and the function code blocks share the same object or variable.

When we change the value of a function argument inside the function code block scope, the value of that variable also changes inside the main body of the python code block scope regardless of the name of the argument or variable.

This concept behaves differently for both mutable and immutable arguments in Python.

In Python, integer, float, string and tuple are immutable objects. This means the value of integer, float, string or tuple is not changed in the main block if their value is changed inside the function.

List, dict and set fall in the mutable object category. This means the value of list, dict and set is changed in the calling block if their value is changed inside the function.

Python Immutable Function Arguments

Python immutable objects, such as numbers, tuples, and strings can also be passed by reference like mutable objects, such as list, set, and dict.

Due to state of immutable (unchangeable) objects if an integer or string value is changed inside the function block then it behaves like an object copying.

Inside the function block scope, a new duplicate copy of the object passed is created and manipulated.

Therefore, the function calling block will not notice any changes made inside the function block scope to the immutable object.

Example-1: passing an integer to the function

def abc(a):
    # function block
    a += 1
    print('id of a:', id(a))  # id of y and a are same
    return a
# main or caller block
x = 10
y = abc(x)
# value of x is unchanged
print('x:', x)
# value of y is the return value of the function abc
after adding 1 to argument 'a' which is actual variable 'x'
print('y:', y)
 
print('id of x:', id(x))    # id of x
print('id of y:', id(y))    # id of y, different from x

Output:
id of a: 1655792976
x: 10
y: 11
id of x: 1655792960
id of y: 1655792976

Example-2 : passing string to the function

def abc(a):
    # function block
    a=a.upper()
    print('id of a:', id(a))  # id of y and a are same
    return a
 
# main or caller block
x = 'hello'
y = abc(x)
 
# value of x is unchanged
print('x:', x)
 
# value of y is the return value of the function abc
# after changing the argument 'a' which is actual variable 'x'
print('y:', y)
 
print('id of x:', id(x))    # id of x
print('id of y:', id(y))    # id of y, different from x

Output:
id of a: 61457024
x: hello
y: HELLO
id of x: 63959232
id of y: 61457024
>>>

Example-3: passing tuple to the function

def abc(tup2):
    # function block
    tup2=tup2+(6,)
    print('id of tup2:', id(tup2))  # id of tup2 and tup3 are same
    return tup2
 # main or caller block
tup1 = (1,2,3,4,5)
tup3 = abc(tup1)
 # value of tup2 is unchanged
print('tup1:', tup1)
 # value of tup3 is the return tuple of the function abc
# after changing the tuple 'tup2' which is actual tuple 'tup1'
print('tup3:', tup3)
 print('id of tup1:', id(tup1))    # id of tup1
print('id of tup3:', id(tup3))    # id of tup3, different from tup1

Output:
id of tup2: 56768248
tup1: (1, 2, 3, 4, 5)
tup3: (1, 2, 3, 4, 5, 6)
id of tup1: 56875408
id of tup3: 56768248

Python Mutable Function Arguments

Python mutable objects like dictionary and list are also passed by reference.

If the value of a mutable object is changed inside the function block scope then its value is also changed inside the calling or main block scope regardless of the name of the argument.

Example 1: passing list as an argument

#function definition
def abc(l1):
    l1.append(2)
    print(l1)
    print('id of l1 :',id(l1))
#function calling
l=[1,2,3,4,5]
abc(l)
print(l)
print('id of l: ',id(l))

Output :
[1, 2, 3, 4, 5, 2]
id of l1 : 60852504
[1, 2, 3, 4, 5, 2]
id of l: 60852504

Example -2 : passing dictionary as an argument

#Function definition
def abc(d2):
    d2['e']='egg'
    print(d2)
    print('id of d2: ',id(d2))
# function calling
d1={'a':'apple','b':'ball','c':'cat','d':'dog'}
abc(d1)
print(d1)
print('id of d1: ',id(d1))

Output:
d2= {‘a’: ‘apple’, ‘b’: ‘ball’, ‘c’: ‘cat’, ‘d’: ‘dog’, ‘e’: ‘egg’}
id of d2: 56983152
d1= {‘a’: ‘apple’, ‘b’: ‘ball’, ‘c’: ‘cat’, ‘d’: ‘dog’, ‘e’: ‘egg’}
id of d1: 56983152