[英]Trying to understand a python recursion function
我有以下代码段,通过在“?”位置更改0和1可以精美地生成二进制数。 但是我不明白这段代码是如何工作的。 特别是str_list [idx] =“?”行 。 为什么是“?” 开始在idx位置恢复。
在编写递归时应该如何考虑这一点?
这是代码
def gen_bin(str_list):
if "?" not in str_list:
print "".join(str_list)
return
idx = str_list.index("?")
gen_bin(str_list[:idx] + ["0"] + str_list[idx+1:])
gen_bin(str_list[:idx] + ["1"] + str_list[idx+1:])
str_list[idx] = "?"
gen_bin(list("1??"))
关于如何编写此类递归函数的任何建议都将帮助我变得更好。
谢谢你的时间。,
函数gen_bin()
只是查找第一次出现的?
在输入参数列表中,使用以下行:
idx = str_list.index("?")
然后在该位置插入0
,然后以该新列表作为新参数递归运行:
gen_bin(str_list[:idx] + ["0"] + str_list[idx+1:])
然后在此处插入1
并再次递归运行:
gen_bin(str_list[:idx] + ["1"] + str_list[idx+1:])
如果没有?
在str_list
它只是打印出参数。
该行:
str_list[idx] = "?"
是不必要的,并且完全不执行任何操作,您可以观察到运行以下代码:
def gen_bin(str_list):
if "?" not in str_list:
#print "".join(str_list)
return
idx = str_list.index("?")
gen_bin(str_list[:idx] + ["0"] + str_list[idx+1:])
gen_bin(str_list[:idx] + ["1"] + str_list[idx+1:])
print str_list
str_list[idx] = "?"
print str_list
gen_bin(list("1??"))
返回:
['1', '0', '?']
['1', '0', '?']
['1', '1', '?']
['1', '1', '?']
['1', '?', '?']
['1', '?', '?']
递归定义分为两部分:
终止条件 。 这部分很关键,并且经常首先出现。 终止条件是您测试要知道自己是否“完成”的条件。
通常,递归函数具有某种“自然”终止条件。 例如,斐波那契数列返回到1时结束。阶乘因数返回到1时结束。当您得到一个空列表时,列表处理结束。 字符串处理以空字符串结尾。
无论是什么,任何递归函数都将失败-通常通过无限循环或递归直到发生堆栈溢出-除非您正确定义了终止条件并成功检查了它。
因此,大多数递归函数如下所示:
def recursive_func(arg): if terminating_condition(arg): return simplest_value # more code here recursive_func(reduced_form(arg))
递归关系。 一旦检查(并通过失败)终止条件的测试,就必须调用递归关系。 通常,这意味着执行涉及相同递归函数的形式稍少一些的计算。
例子:
N! := n *(n-1)!
fib(n):= fib(n-1)+ fib(n-2)
len(head:tail):= 1 + len(tail)
真实的例子
让我们看一下您的示例:
def gen_bin(str_list):
if "?" not in str_list:
print "".join(str_list)
return
idx = str_list.index("?")
gen_bin(str_list[:idx] + ["0"] + str_list[idx+1:])
gen_bin(str_list[:idx] + ["1"] + str_list[idx+1:])
str_list[idx] = "?"
gen_bin(list("1??"))
很明显,此功能遵循经典结构。 第一段是终止条件的检验。 在这种情况下,终止条件是不存在“?” 在要替换的字符串中。
函数的其余部分专用于递归关系。 在这种情况下,这包括替换首次出现的“?” 在带有“ 0”或“ 1”的字符串中重复执行。
我认为这不是很好的代码。 首先,最后的赋值str_list[idx] = "?"
, 什么也没做。 我怀疑该代码是最近修改的。 它可能在适当的位置编辑了str_list
,直接在str_list[idx]
设置了“ 0”和“ 1”,而不是使用切片。
更重要的是,这不是一个好代码,因为它所做的只是打印结果。 如果它返回一个二进制字符串列表,而不是尝试打印它们,那将是一个更好的功能。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.