在此代码中:
def is_even(x):
if x == 0:
return True
else:
return is_odd(x-1)
def is_odd(x):
return not is_even(x)
print(is_even(2))
print(is_odd(2))
我一直在脑子里想着这个,并想知道它是如何运作的。在我看来,x
中的is_even(x)
最终每次都会返回True
。但是,当我运行代码时,它完全正常并且适当地返回True
和False
。有人能解释一下这是怎么回事吗?
我理解递归的基本概念,并完全理解着名的因子示例是如何工作的。然而,这个我很难绕过我的脑袋。
现在感到无能......
答案 0 :(得分:9)
在找到基本情况之前,总是有助于分解递归关系。
is_even(2) => return is_odd(1)
=> return not is_even(1)
=> return not is_odd(0)
=> return not not is_even(0)
=> return not not True
=> return True ---- (1)
is_odd(2) => return not is_even(2)
=> return not True [from (1)]
=> return False
通常,从您的递归函数中,很容易发现is_even(n)
将返回[not not not ... n times] True
,而is_odd(n)
将返回[not not not ... n - 1 times] True
。因此not
s的数量因此最终表达式取决于n
(aha!)。那么,这肯定是一种迂回的方式来询问是否
n % 2 == 0
答案 1 :(得分:5)
添加几个print
语句,您将看到它正在做什么:
from __future__ import print_function
def is_even(x):
if x == 0:
print('True')
return True
else:
return is_odd(x-1)
def is_odd(x):
print('not', end=' ')
return not is_even(x)
>>> is_even(5)
not not not not not True
False
>>> is_odd(5)
not not not not not not True
True
答案 2 :(得分:3)
与大多数情况一样,简单地包含print
来跟踪执行可能会有所帮助:
def is_even(x):
print('check if {} is even'.format(x))
if x == 0:
return True
else:
return is_odd(x-1)
def is_odd(x):
print('check if {} is odd'.format(x))
return not is_even(x)
然后在你的情况下:
>>> print(is_even(2))
check if 2 is even
check if 1 is odd
check if 1 is even
check if 0 is odd
check if 0 is even
True
>>> print(is_odd(2))
check if 2 is odd
check if 2 is even
check if 1 is odd
check if 1 is even
check if 0 is odd
check if 0 is even
False
所以基本上它会减少数字,直到它0
为止。重点是not
次呼叫中累积了多少is_odd
个not
。如果它是偶数个True
s,那么结果将为False
,否则为{{1}}。
答案 3 :(得分:2)
这是真的;递归应该在is_even
内结束。
当这种情况发生时,你会知道你拥有的号码是0
。
现在让我们倒退吧。最终状态将通过两种情况实现 - 直接呼叫is_even(0)
或来自is_odd(0)
的呼叫。在第一种情况下 - 结果都很好。在第二个 - 结果将返回到is_odd
函数,否定,因此将是假的 - 给出正确的结果。
现在,这里缺少的部分来了 - 递归:为了达到这种状态,我们需要每次都减少参数,将其传递给相反的函数 - 这正是我们用return is_odd(x-1)
得到的。
注意:最终这种递归会导致True
返回的值is_even
的一系列否定。此链的长度为x
,其中x
是您的号码,因此奇数或甚至是对应的。
因此,以下代码也会这样做(缺少is_odd
好的副作用):
def is_even (x):
res = True
while x:
res = not res
x -= 1
return res
答案 4 :(得分:1)
我认为所有其他答案都很棒,但理解问题的最简单方法可能是答案得到多少次而不是#34;不是。每次通过is_odd函数时,都会将no添加到最终答案中。 True将永远返回,但对于偶数,总会有偶数个nots相互抵消,但对于奇数,它们总是有奇数个nots因此返回false。