我是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。
我正在试图弄清楚如何使这项工作..谢谢你们!
答案 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。
我做对了吗?