python在函数内部调用函数

时间:2014-09-10 23:30:55

标签: python function recursion

我是CS的初学者,我一直在尝试自己编写Python书。

我目前正在接受递归,但我有点卡住了。

练习要求我编写一个名为do_n的函数,它接受一个函数对象和一个数字n作为参数,并且调用给定函数n次。

这是我的代码

def countdown(n):
    if n<= 0:
        print 'Blastoff'
    return
else:
    print n
    countdown(n-1)

def do_n(f(n), x):
    if x<=0:
        return
    else:
        f(n)
        do_n(f, x-1)

do_n(countdown(3), 3)

当我这样做时,由于def do_n(f(n),x)中的语法无效而出现错误。如果我将其更改为

def do_n(f, x):
    if x<=0:
        return
else:
    f(n)
    do_n(f, x-1)

有一个错误,因为在else语句中没有定义n。

我正在试图弄清楚如何使这项工作..谢谢你们!

3 个答案:

答案 0 :(得分:0)

你的第二个例子几乎就在那里。它需要一个函数f和一个最大计数x。 n不存在,因为您尚未编写循环以生成n的值。结果是python有内置的

def do_n(f, x):
    for n in range(x):
        f(n)

现在do_n采用函数对象f和计数x,然后调用函数计数次数。注意f(函数对象)和f(n)之间的区别(使用值n调用f的结果)。当你想调用do_n时,你可以这样做:

do_n(countdown, 3)

不喜欢

do_n(countdown(3), 3) # badness

最后一个调用倒计时,然后调用do_n及其结果。

答案 1 :(得分:0)

def print_n(s,n):
    if n<=0:
        return
    else:
        print(s)
        print_n(s,n-1)

def do_n(f,s,n,x):
    if x<=0:
        return
    else:
        f(s,n)
        do_n(f,s,n,x-1)

do_n(print_n,'Hello',2,2)

答案 2 :(得分:0)

这是一个棘手的事情。

基本上,解决方案是:

def do_n(f, n):
    if n <= 0:
        return
    f(n)
    do_n(f, n-1)

但是,如果您实际上尝试将其与print_n结合使用,那么所有地狱都将变得一团糟。

首先,我们必须在上面的代码中再添加一个参数s,以便能够将要打印的任何字符串传递n次。

第二,上面的do_n应该能够将任何传递的函数重复n次,只要该函数不会干扰do_n。不幸的是,这正是这里发生的情况。

这本书的分配似乎很清楚:“ ...编写一个名为do_n的函数,该函数接受一个函数对象和一个数字n作为参数,并调用给定函数n次...”或换句话说do_n调用传递给它的任何函数n次。您可能会想,如果我们传递s ='Hello'且n = 3,那么do_n(f,s,n)应该输出'Hello'9次...因为print_n('Hello',3)打印'Hello'3次并且do_n(print_n,'Hello',3)应该使结果翻三倍。。。

实际发生的是在第一次递归中,do_n确实打印了3次“ Hello”,因为print_n如此说。但是在下一个实例中,do_n仅打印两次“ Hello”,因为它在前一个实例中减去了3-1,现在又减去了print_n('Hello',2)。由于相同的原因,在最后一个实例中,do_n仅打印一次“ Hello”。因此,“ Hello”输出的总数为6。

最后,如果使用FOR LOOP而不是递归来定义do_n,则实际上将获得9个输出的正确结果:

def print_n(s, n):
    if n <= 0:
        return
    print(s)
    print_n(s, n-1)

def do_n(f, s, n):
    for i in range(n):
        f(s, n)

do_n(print_n, 'Hello', 3)

P.S。 在Think Python 2E的第52页上,我们鼓励对循环使用递归:

“对于像这样的简单示例,使用for循环可能会更容易。但是稍后我们将看到难以通过for循环编写并且易于通过递归编写的示例,因此最好早点开始。 “

但是,在此特定练习中,使用递归会强制输出与赋值冲突,因为do_n和print_n相互矛盾,因为在递归的帮助下构造do_n会错误地减少n。

我做对了吗?