Python新手提问:在自定义函数中调用自定义函数,引发局部变量值自发改变的问题

是这样的,我没有找到Python里面的list数乘与加减运算,于是自己定义了它们,代码如下:

   def ntl(n1: float, list1: list) -> list:

for i in range(0, len(list1)):

list1[i] *= n1

return list1

def lsb(list1: list, list2: list) -> list or bool:

if len(list1) != len(list2):

return False

for i in range(0, len(list1)):

list1[i] -= list2[i]

return list1

前面的ntl是向量数乘(n times list),后面的lsb是向量相减(list subtraction)。这两个函数在后面被调用,调用的地方是一个解方程算法:即解决au+bv=gcd(u,v)这样的线性丢番图方程,或者数论里面提到的裴蜀(Bézout)定理,其中u,v是两个正整数,gcd是最大公约数。
代码如下:

    def bezout(n1: int, n2: int) -> int or bool:

if type(n1) != int or type(n2) != int:

return False

list1 = [1, 0, n1]

list2 = [0, 1, n2]

while list1[2] != 0:

list3 = list1 # 01

list1 = lsb(list2, ntl(int(list2[2] / list1[2]), list1)) # 02

list2 = list3 # 03

return list2

我使用Pycharm社区版运行这些代码。在调试时,我选择了bezout(9785, 18967)进行验算。然而在断点# 02处,每当运行到第3轮循环时,list3的值都会自发改变,见下面的截图:
这是上一步

这是下一步,此时没有对list3进行操作,但list3值已经改变

代码中没有全局变量,我认为不同函数中的局部变量不会相互影响,况且在之前的代码中,list3没有出现过。这个算法本身是没有问题的。bezout这个函数输出的结果在算数上是成立的,最终输出:
6257064 x 9785 - 3227994 x 18967 == 9042 然而化简后的结果应该是:692 x 9785 - 357 x 18+67 == 1
我不知道到底发生了什么,请各位帮忙看看,多谢!

回答:

代码

list1 = lsb(list2, ntl(int(list2[2] / list1[2]), list1))

这里的 list1 是一个列表, 一个可变对象, 又因为在函数 lsb 中, 对于list1的修改, 是直接修改当中的元素, 又因为它是可变对象, 所以实际上, 你修改的是全局的 list1, 而不是你想象中的 局部变量list1

如果真的想要实现你想要的那种, 局部变量list1, 那就用深拷贝的方式吧

import copy

list1 = lsb(list2, ntl(int(list2[2] / list1[2]), copy.deepcopy(list1)))

关于python函数" title="python函数">python函数传参细节, 可参考: Python 函数参数引用(传值/传址)/copy/deepcopy

PS:
文中代码:

if type(n1) != int or type(n2) != int:

return False

在判断对象类型时, 不应该用这种方式, 而是用isinstance函数:

if not isinstance(n1, int) or not isinstance(n2, int):

return False

以上是 Python新手提问:在自定义函数中调用自定义函数,引发局部变量值自发改变的问题 的全部内容, 来源链接: utcz.com/a/157589.html

回到顶部