Calling a function twice but in second time, first list which was returned by the function goes as argument in python

Viewed 28

in function entery when the first time argument is going (n, a) it's working fine a goes as empty list initialized with 0. but in the second time when b matrix is going as argument (n, b), so at that time li list which was returned by the function before is going as matrix b rather than empty matrix b which was initialized by 0. someone please help me finding error in my code.

#funtion for taking input in matrix
def entery(n, li):
    print(li)
    print('enter the element of matrix: ')
    for a in range(n):
        for b in range(n):
            no = int(input())
            li[a][b]= no
    return li #returning the updated matrix

n = int(input('dimensions of square matrix:'))
a = []
c = []
result = []
#creating matrix
for i in range(n):
    b =[]
    for j in range(n):
        b.append(0)
    a.append(b)
    c.append(b)
    result.append(b)

print("a matrix",a)
print("c matrix",c)
fm = []
sm = []
#calling function
fm = entery(n,a)
sm = entery(n,c)

print(fm)
print(sm)
#addition of matrix
for x in range(n):
    for y in range(n):
        result[x][y] = fm[x][y] + sm[x][y]

print(result)

the output is shown below-

output:
dimensions of square matrix:2
a matrix [[0, 0], [0, 0]]
c matrix [[0, 0], [0, 0]]
[[0, 0], [0, 0]] #when called first time
enter the element of matrix: 
11
22
33
44
[[11, 22], [33, 44]] # but in second time...
enter the element of matrix: 
12 
23
34
45
[[12, 23], [34, 45]]
[[12, 23], [34, 45]]
[[24, 46], [68, 90]]
1 Answers

All parameters (arguments) in the Python language are passed by reference. It means if you change what a parameter refers to within a function, the change also reflects back in the calling function.


So when you pass a mutable list like a to the function, there is a chance that the a list to get changed, like in the entry() function which you're inserting numbers to the list.

However if you check the value of list c after the first function call, you'll notice that it has been changed ,too.

[...]
#calling function
fm = entery(n,a)
print(f"a: {a}")
print(f"c: {c}")
[...]

result:

dimensions of square matrix:2
a matrix [[0, 0], [0, 0]]    
c matrix [[0, 0], [0, 0]]    
[[0, 0], [0, 0]]
enter the element of matrix: 
11
22
33
44
a: [[11, 22], [33, 44]]
c: [[11, 22], [33, 44]]

The reason is that:
There is a reference between a and c. When you first initialized both a and c, you put same list b in both lists:

[...]
for i in range(n):
    b =[]
    for j in range(n):
        b.append(0)
    a.append(b)       # <------
    c.append(b)       # <------
    result.append(b)
[...]

As you know b is also a list so when you put it in both a and c lists, the lists in "a and c lists" will have same ids and references, therefor if we change one of those lists, the other will be also changed.


You can prevent this, by using a copy of b when initiating the a and c lists, like this:

#creating matrix
for i in range(n):
    b =[]
    for j in range(n):
        b.append(0)
    a.append(b[:])    # <---- This makes a copy of list "b"
    c.append(b[:])
    result.append(b[:])

Therefor the result will be:

dimensions of square matrix:2
a matrix [[0, 0], [0, 0]]    
c matrix [[0, 0], [0, 0]]    
[[0, 0], [0, 0]]
enter the element of matrix: 
11
22
33
44
[[0, 0], [0, 0]]
enter the element of matrix:
12
23
34
45
[[11, 22], [33, 44]]
[[12, 23], [34, 45]]
[[23, 45], [67, 89]]
Related