2015-02-09 98 views
-1
def myLog(x,b): 
    def logCall(x,b,cnt): 
     if (int(x) < b): 
      return cnt 
     else: 
      cnt+= 1 
      logCall(int((int(x)/b)),b,cnt) 

    return logCall(x,b,0) 

res=myLog(16,2) 
print res 

該函數應該返回一個值爲4,但它返回無。當我打印cnt的值時,我看到了正確的值。但是,當我回來了,我得不到任何的價值python函數沒有返回正確的值

+0

這種尾遞歸函數只是_begging_被轉換爲迭代解決方案! – 2015-02-09 15:04:42

+0

輝煌。非常感謝您的幫助 – 2015-02-09 15:08:40

回答

6

不必返回遞歸調用:

else: 
    cnt += 1 
    logCall(int((int(x)/b)),b,cnt) 

你發揮作用,而不是僅僅止於此,您將返回None代替,默認爲不結束功能明確的return

返回遞歸結果:

else: 
    cnt += 1 
    return logCall(int((int(x)/b)),b,cnt) 

遞歸調用並不神奇地讓調用框架返回太多;與其他任何函數調用一樣,logCall()的調用爲,但仍需要處理返回的值。

隨着這種變化,你的代碼返回預期值:

>>> def myLog(x,b): 
...  def logCall(x,b,cnt): 
...   if (int(x) < b): 
...    return cnt 
...   else: 
...    cnt+= 1 
...    return logCall(int((int(x)/b)),b,cnt) 
...  return logCall(x,b,0) 
... 
>>> myLog(16,2) 
4 

沒有必要使用int()所有的地方;你的輸入已經是整數。如果您只想進行整數除法,請使用//地板分割算子。

您可能想要添加一些空白以提高可讀性,並且else是可選的,因爲如果if測試爲true,則您已經退出該函數。大號

最後但並非最不重要的,你可以給cnt一個默認值,無需窩你的函數:

def myLog(x, b, cnt=0): 
    if x < b: 
     return cnt 
    return myLog(x // b, b, cnt + 1) 
+0

爲什麼在這裏需要類型轉換if(int(x) 2015-02-09 15:06:59

+0

@AvinashRaj:我沒有看到實際的代碼本身。好點子。 – 2015-02-09 15:09:29

0

一個變種,Python 3中關閉;

def myLog(x,b): 
    def logCall(cnt=0): 
    nonlocal x 
    if x < b: 
     return cnt 
    x /= b 
    return logCall(cnt+1) 
return logCall 

res=myLog(16,2) 
res() 

for Python 2 closure,pass list;

def myLog(l): 
    def logCall(cnt=0): 
    if l[0] < l[1]: 
     return cnt 
    l[0] /= l[1] 
    return logCall(cnt+1) 
return logCall 

res=myLog(16,2) 
res()