2015-02-09 99 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()