2014-05-13 38 views
2

我做了一個非常簡單的函數,它接受號的列表,並返回一些數字四捨五入號碼清單:Python中的遞歸函數悖論..它如何解釋?

def rounded(lista, digits = 3): 
    neulist = [] 
    for i in lista: 
     neulist.append(round(i, digits)) 
    return neulist 

然而,我錯把函數本身的代碼,而不是內置round()的(如在下面的示例):

def rounded(lista, digits = 3): 
    neulist = [] 
    for i in lista: 
     neulist.append(rounded(i, digits)) 
    return neulist 

和得到這個輸出:

Traceback (most recent call last): 
    File "<pyshell#286>", line 1, in <module> 
    rounded(a) 
    File "<pyshell#284>", line 4, in rounded 
    neulist.append(rounded(i, digits)) 
    File "<pyshell#284>", line 3, in rounded 
    for i in lista: 
TypeError: 'float' object is not iterable 

的問題是:如何做解釋者知道在評估函數rounded()本身時必須應用函數rounded()?無論如何,rounded()是一個函數,如果它正試圖解釋這個函數,那麼它是一個函數嗎?是否有兩種循環程序來評估&解釋函數?或者我在這裏得到錯誤?

+0

題外話,就像旁註:'round = lambda l:map(lambda x:round(x,1),l)' – Pavel

回答

4

函數是一個對象。它是在定義時創建的,而不是在被調用時創建的,所以如果Python不知道如何使用它,它會在任何調用完成之前產生錯誤。
但是,你用一個列表來調用它。在迭代過程中,該函數與列表中的第一項遞歸調用 - 大概是一個浮點數。以此浮點數作爲參數,for i in lista:不再有意義,並且您有錯誤。

+2

要增加一些我認爲是正確的答案:在'for'循環的內部稱爲'rounded(a_list)',從該列表中提取第一項,'i',並調用'四捨五入(i,數字)'。由於'i'是一個浮點數,所以在第二次'round'調用時會遇到錯誤,您嘗試在i中執行'for new_i'。 – huu

+0

你是對的,當我調用函數時,錯誤被提示,現在當我實例化它時,所以我想這只是我的錯覺。感謝您的快速和明確的答案! – DaniPaniz

0

你剛剛偶然發現recursion

遞歸函數在編程中非常常見。考慮下面的(幼稚)函數計算n日fibbonacci號:

def fib(x): 
    if x<=2: 
     return 1 
    else: 
     return fib(x-1)+fib(x-2) 

功能知道它自稱,因爲函數定義是隻要解釋達到fib(x):指出。從那時起,fib被定義。特別是對於python,由於它是一種動態類型語言,因此,如果使用整數,字符串或浮點數來調用函數,則沒有區別 - 重要的是該函數只需要一個參數。

0

確實有兩個過程發生在這裏。該函數按照在源文本中遇到的方式進行編譯,然後再調用該函數。函數的主體包括對rounded的調用,但實際上這是跟蹤函數的名稱。檢查了這一點:

def fun1(x): 
    if x == 0: 
     print x 
    else: 
     fun1(x-1) 

fun2 = fun1 

def fun1(x): 
    print x 

fun2(3) 

這裏我們定義fun1()帶有明顯遞歸調用本身。但是,在重新定義fun1()之後,函數的第一個定義中的調用現在完全引用了不同的函數。