Python 在递归函数中传参问题

2018/04/16 Python

在 Python 的递归函数中传参的时候,企图传引用遇到的问题。

最近在写 Python 的递归函数的时候遇到一个问题,企图传一个引用型参数作为计数器,失败了。

以经典的递归函数的例子来说明。
最初的写法:

def func(n, count):
    count += 1
    if n == 1:
        return 1
    return n * func(n-1, count)

count = 0
n = 5
res = func(n, count)
print('function result is:' + str(res))
print('counter is:' + str(count))

对于这个函数,我期望的 count 的值是 5,然而实际的结果是:

function result is:120
counter is:0

这里涉及到 Python 的传参机制的问题:

Python 不允许程序员选择采用传值还是传引用。Python 参数传递采用的肯定是“传对象引用”的方式。 这种方式相当于传值和传引用的一种综合。如果函数收到的是一个可变对象(比如字典或者列表)的引用,就能修改对象的原始值--相当于通过“传引用”来传递对象。如果函数收到的是一个不可变对象(比如数字、字符或者元组)的引用,就不能直接修改原始对象--相当于通过“传值’来传递对象。

因此,有两种修改方法。其一,是把 count 变成一个可变对象,例如:

def func(n, count):
    count[0] += 1
    if n == 1:
        return 1
    return n * func(n-1, count)

count = [0]
n = 5
res = func(n, count)
print('function result is:' + str(res))
print('counter is:' + str(count[0]))

运行结果为:

function result is:120
counter is:5

不过强行把整型变量变成列表,也挺奇怪的。更正常的改法是把 count 作为返回值返回,这样:

def func(n, count):
    count += 1
    if n == 1:
        return 1, count
    tmp_n, count = func(n-1, count)
    return n * tmp_n, count

count = 0
n = 5
res, count = func(n, count)
print('function result is:' + str(res))
print('counter is:' + str(count))

运行结果为:

function result is:120
counter is:5

不过这样写,用了中间变量,也不是很优美。以后看看有没有更合适的解法。

Reference

python函数传参是传值还是传引用?

Search

    Table of Contents