Python中的值传递和地址传递
Python作为一种弱类型的语言,为了方便使用者,省掉了很多不必要的麻烦。但是对于C和C++语言来说,指针是必不可少的。虽然python中没有指针的概念,但是也要时刻记住,对一个变量操作,是对变量本身操作,还是只对形参进行操作。因为最开始自己并没有注意这一点,所以导致自己的程序出了挺大的问题,还查不到相应的问题所在。
踩坑记录
题目的简单描述:返回一棵二叉树的节点的数量。
题目很简单,我最开始写的代码就是下面这样:
def countNodes2(self, root):
def helper(root, sum):
if not root:
return 0
sum += 1
helper(root.left, sum)
helper(root.right, sum)
return sum
count = helper(root, 0)
return count
写完之后觉得非常正确,但是跑了个测试,发现并不对,每次返回值都是1, 我就在想了,为什么会产生这样的问题,于是开始debug,加一些中间输出变量,变成了下面这样:
def countNodes2(self, root):
def helper(root, sum):
if not root:
return 0
sum += 1
print("this is test line!")
helper(root.left, sum)
helper(root.right, sum)
return sum
count = helper(root, 0)
return count
我其实只是想看一下sum一共执行了几次,果不其然,其实是按照正确的执行了,假设你的测试用例有3个节点,那么就一共输出了3次。怎么看都是正确的。于是就在线,到底是哪里出了问题,想了一下,应该是每次递归进去的时候,每次只是更改sum这个形参的值,只是对形参进行操作。实际上也就是每次递归调用的时候,都会新生成一个sum变量,而这个变量的声明周期只是该方法的执行周期,当该方法死掉的时候,sum值也跟着消亡了。并不会对之前的sum进行累加。如果想进行累加的话,就需要对同一个sum值进行操作,而不是每次生成新的变量。所以,知道了问题所在,就可以比较快速的解决问题。那么也就是将值传递改为地址传递即可。更改为如下的程序即可:
def countNodes(self, root) -> int:
self.sum = 0
def helper(root):
if not root:
return 0
self.sum += 1
helper(root.left)
helper(root.right)
helper(root)
return self.sum
如上图所示,这样即可得到正确的结果。因为这样的参数sum属于地址传递了,每次递归的时候,都是对原数据进行更改。
总结
python中地址传递的变量有:list, tuple, dict, 对象等。上述方法中使用一个list,每次append一个元素,最后list的元素个数就是二叉树的节点个数,也可以说明,list是地址传递。
值传递的变量有:普通类型的变量,比如int型,字符串等,都是属于值传递,每次操作的时候并不会对原值进行更改,更改的只是新生成的值。