[英]Python calling a function inside a function
我是 CS 的初學者,我一直在嘗試自己完成一本 Python 書(Think 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)
出現錯誤,因為n
未在else
語句中定義。
我怎樣才能使這項工作?
你的第二個例子就快到了。 它需要一個函數 f 和一個最大計數 x。 n 不存在,因為您還沒有編寫循環來為 n 生成值。 原來python有一個內置的
def do_n(f, x):
for n in range(x):
f(n)
現在 do_n 接受一個函數對象 f 和一個計數 x,然后調用函數 count 次。 請注意f
(函數對象)和f(n)
(使用值 n 調用 f 的結果)之間的區別。 當你想調用 do_n 時,你可以這樣做:
do_n(countdown, 3)
不喜歡
do_n(countdown(3), 3) # badness
最后一個調用 countdown ,然后用它的結果調用 do_n 。
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)
這是一個棘手的問題。
基本上,解決方案是:
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)
PS 在 Think Python 2E 的第 52 頁上,我們鼓勵在 for 循環上使用遞歸:
“對於像這樣的簡單示例,使用 for 循環可能更容易。但是我們稍后會看到使用 for 循環難以編寫而使用遞歸編寫易於編寫的示例,因此最好盡早開始。”
然而,在這個特定的練習中,使用遞歸強制輸出與賦值沖突,看到 do_n 和 print_n 彼此不一致,因為在遞歸的幫助下構造 do_n 錯誤地減少了每個實例中的 n。
我做對了嗎?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.