两次调用函数,但在第二次,函数返回的第一个列表在 python 中作为参数

Posted

技术标签:

【中文标题】两次调用函数,但在第二次,函数返回的第一个列表在 python 中作为参数【英文标题】:Calling a function twice but in second time, first list which was returned by the function goes as argument in python 【发布时间】:2021-12-01 14:38:25 【问题描述】:

在函数输入中,当第一次参数为 (n, a) 时,它工作正常 a 作为用 0 初始化的空列表。但在第二次时,当 b 矩阵作为参数 (n,b) 时,所以在之前由函数返回的 li 列表将作为矩阵 b 而不是由 0 初始化的空矩阵 ​​b。有人请帮我在我的代码中查找错误。

#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)

输出如下图-

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】:

Python 语言中的所有参数(参数)都是passed by reference。这意味着如果您更改 function 中的参数所指的内容,更改也会反映在调用函数中。


因此,当您将mutable list (如a)传递给函数时,a 列表可能会发生更改,例如在您向列表中插入数字的entry() 函数中。

但是,如果您在第一次函数调用后检查 list c 的值,您会注意到它也已更改。

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

结果:

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]]

原因是:ac 之间有一个引用。当您第一次初始化 ac 时,您将相同的列表 b 放入两个列表中:

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

如您所知,b 也是一个列表,因此当您将其同时放入 ac 列表时,“ac 列表”中的列表将具有相同的 ids 和references,因此如果我们更改其中一个列表,另一个也会更改。


您可以通过在启动ac 列表时使用b 的副本来防止这种情况,如下所示:

#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[:])

因此结果将是:

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]]

【讨论】:

以上是关于两次调用函数,但在第二次,函数返回的第一个列表在 python 中作为参数的主要内容,如果未能解决你的问题,请参考以下文章

UIView 仅在第二次调用后显示

Apollo 客户端 writeQuery 更新存储,但 UI 组件仅在第二次函数调用后更新

Excel UDF 被调用两次,每次返回不同的值

为啥我的 FFI 函数的第二次调用无法匹配字符串比较?

Python:不能在类中使用函数两次,TypeError:'list'对象不可调用,为什么? [关闭]

HttpURLConnection.getResponseCode() 在第二次调用时返回 -1