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没有出现过。这个算法本身是没有问题的。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 copylist1 = 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