Python 这个递归二进制代码函数是如何工作的?
目前正在学习递归,对于这个函数到底是如何工作的感到困惑。它应该返回一个长度为r的二进制代码字符串列表(根据docstring),您可以将0和1添加到每个“二进制代码”中,以获得下一个“二进制代码”中的字符串数量 现在我感到困惑的是小=代码(r-1)部分Python 这个递归二进制代码函数是如何工作的?,python,recursion,Python,Recursion,目前正在学习递归,对于这个函数到底是如何工作的感到困惑。它应该返回一个长度为r的二进制代码字符串列表(根据docstring),您可以将0和1添加到每个“二进制代码”中,以获得下一个“二进制代码”中的字符串数量 现在我感到困惑的是小=代码(r-1)部分 如果我对此进行跟踪,它似乎只是不断地调用函数,直到'r==0'为真,在这种情况下,它最终返回空?将0和1添加到空列表中似乎只能得到['0','1']。该函数如何使用该基本情况返回长度为r的所有二进制代码。让我们看看r=2的情况: 代码(2) r不
如果我对此进行跟踪,它似乎只是不断地调用函数,直到'r==0'为真,在这种情况下,它最终返回空?将0和1添加到空列表中似乎只能得到['0','1']。该函数如何使用该基本情况返回长度为r的所有二进制代码。让我们看看r=2的情况:
代码(2)
r不是0,所以我们不返回任何内容small
get被分配了code(1)
的返回值。所以为了继续,我们必须先看看code(1)
返回的内容
代码(1)
同样,r不是0。因此,此调用中的small
设置为codes(0)
。我们必须查看code(0)
返回的内容
代码(0)
这是硬编码以返回['']
。让我们回到执行code(1)
代码(1)
(续)
small
设置为['']
,现在我们迭代该列表的每个元素,但首先,我们定义一个空列表lst
<代码>小只有一个元素,'
。因此,我们将两个元素附加到lst
:'+'0'
(这只是'0'
),同样地'1'
然后我们返回列表。现在我们知道codes(1)
返回['0','1']
。让我们回到执行code(2)
代码(2)
(续)
small
获得代码(1)
的结果,我们现在知道它是['0','1']
。现在我们再次初始化一个空列表lst
,并在small
上迭代。对于small
(我们有两个)中的每个元素,我们将两个元素附加到lst
:这意味着0
我们将0
和1
附加到00
和01
,对于1
,我们将这两个元素附加到0
中,以获得10
和11
因此,codes(2)
返回['00','01','10','11']
。
通常,您会看到,对于codes(n)
结果中的每个元素,codes(n+1)
将返回两个元素:分别附加了0
和1
的元素。因此,返回列表的长度总是应该加倍
重要的是要理解,尽管名称
small
和lst
是固定的,但它们在每次调用code
时都指向不同的对象,我认为这可能是造成混淆的原因。递归函数的关键是知道何时退出!每个递归函数,或一组相互递归函数中的至少一个成员,都将有一个测试,该测试只会说,“这是任何函数的结束、开始、底部或顶部,因此结果是一个常量、一个空字符串或一个空列表,或其他任何内容。”
终止
您的终止条件是r==0
。当要求所有长度为零的二进制字符串时,您将返回一个包含空字符串的列表。为什么?因为没有这样的字符串,但是为了生成一个更长的字符串(见下文),我们需要一个附加的字符串
迭代
如果不是在“到此结束”的情况下,递归函数需要计算过程中的“更多步骤”。由于函数的终止条件基于字符串的长度,因此迭代条件也可能基于字符串长度。在本例中,通过缩短字符串来递归。因此,您可以通过使(缩短的)字符串变长来进行迭代
如果您有一个像“0”这样的二进制字符串,那么比它长一个字符的所有可能的二进制字符串是什么?它们是['01','00']或['10','00'],这取决于你是想让字符串在结尾还是开头变长
那么,如何列出长度为N的二进制字符串呢?首先,你得到每一个可能的长度为N-1的二进制字符串,然后你为每一个字符串生成两个字符串,附加一个0或一个1
如何获得长度为N-1的所有可能的二进制字符串?您可以调用此函数,codes(N-1)
,它将返回它们。别担心怎么做
因此
small=codes(r-1)
是您的函数获取的字符串列表短一个字符--r-1
部分。然后对每一个进行迭代,得到两个!一个是字符串加上“0”,第二个是字符串加上“1”。迭代了所有小的-er字符串后,就有了一个较长字符串的列表。您可以将此结果传递给任何请求它的人(可能是您自己,试图制作更长的字符串)。“不必担心如何”。正是这一部分在困扰着我。在不知道内部发生了什么的情况下,就把它当作理所当然的工作,虽然现在我想这是有意义的,但对我来说,它没有那么直观的意义。诀窍是,递归函数将以两种方式之一工作-要么你将得到终止情况,要么你将得到一个迭代情况。因此,不要担心它在一个级别上是如何工作的。只是担心它在这个级别上是如何工作的。
def codes(r):
'''(int) -> list of str
Return all binary codes of length r.
>>> binary_codes(2)
['00', '01', '10', '11']
'''
if r == 0:
return ['']
small = codes(r-1)
lst = []
for item in small:
lst.append(item + '0')
lst.append(item + '1')
return lst