python中的值传递--记一次踩坑记录

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型,字符串等,都是属于值传递,每次操作的时候并不会对原值进行更改,更改的只是新生成的值。

你可能感兴趣的:(leetcode)