python递归函数分叉树枝_python初学 数据分叉情况下的函数递归

对于python中的函数递归,其实用while和for循环可以等价的实现。平时较少用到,但是在某些特定情况下比较方便实现一些功能。

对于没有数据分叉的函数递归,比较简单。如:

defcal(n):print(n)if n >0:return cal(int(n/2))else:return 'n=0 done'

print(cal(10))

输出:10

5

2

10

n=0 done

通过层层调用,达到条件后,结束调用,再层层返回。

但是对于有数据分叉的函数递归,如对嵌套列表的遍历、查询,就会比较绕一些

先看没有分叉的:

给定一个节点,在menus找到他,如果该节点存在,打印出来,并返回true,如果不存在,就返回false

menus = [

{

'text': '北京',

'children':[

{'text':'昌平','children':[

{'text':'沙河','children':[]}

]}]}]

def find_menu(menu,city):

if menu:

for i in menu:

if i['text'] != city:

return find_menu(i['children'],city) #如果本层没有city,则会深入到下一层

else:

print(city)

return True

else:

return False

city=input('>>>>')

print(find_menu(menus,city))

可以看到比较容易就实现了。

但是这里menus有一个特点,就是每一级menus都只有一个元素,找过这个元素,本级就找完了。如果有多个元素呢?这就意味着,你把元素1里面嵌套的元素遍历一遍之后,还需要回头去找元素2但是如果把meuns改变一下,难度就会大大增加。

menus =[

{'text': '北京','children':[

{'text':'朝阳','children':[]},

{'text':'昌平','children':[

{'text':'沙河','children':[]},

{'text':'回龙观','children':[]},

]},

]

},

{'text':'上海','children':[

{'text':'宝山','children':[]},

{'text':'金山','children':[]}

]

}

]

对于这个menus,如果我们继续用刚才的递归函数,就会达不到目的。

deffind_menu(menu,city):ifmenu:for i inmenu:if i['text'] !=city:return find_menu(i['children'],city) #如果本层没有city,则会深入到下一层

else:print(city)returnTrueelse:returnFalse

city=input('>>>>')print(find_menu(menus,city))>>>>朝阳

朝阳

True>>>>沙河

False>>>>宝山

False

可以看到,只有在找每级的第一个元素,即menus[0][0]...才可以,其余的全部都会返回False。这是因为,使用for循环,在每级都是从第一个元素开始找,找不到,就会递归至下一级的for循环,依然从下一级的第一个元素开始找起,直到最后一层,如何还是没有找到,就会return False,返回返回上一级。上一级继续执行retur语句,返回False,再返回上一级。以此类推,直到完全退出。这里我们发现,for循环根本就没有执行完,就直接退出了程序,达不到遍历的效果。

如果想将for循环进行完,就不能在find_menu(menus,city)前使用return,就不能将返回值一层一层向上传递,同样是不行的。

换个角度思考,什么时候可以结束for循环呢,就是找到 city情况下。如果找不到city,我们就需要让for循环一直执行下去,直到执行完,还是找不到的话,就说明没有city,这时可以返回false。

这么我们可以加一个条件语句,

if 找到了city

就return

那么可以把代码改一下:

deffind_menu(city,menu):ifmenu:for i inmenu:if i['text'] !=city:

flag=find_menu(city,i['children'])if flag==True:returnTrueelse:print(city)returnTrueelse:returnFalseelse:return False

可以以最后find_menu的执行结果来判断,如果找到了city,find_menu就会返回True。如何把这个值一层一层传上去呢。我们可以让一个参数来接收返回值,并逐级上传。

也可以去掉这个参数,直接用find_menu的值。

由于menu为空的话, 肯定是没有找到city,for循环肯定也是执行完了,所以与最外层if对应的else也可以去掉。因为for--else已经返回了false。

deffind_menu(city,menu):ifmenu:for i inmenu:if i['text'] !=city:if find_menu(city,i['children']):returnTrueelse:print(city)returnTrueelse:returnFalse

这样就完成了一个有数据分叉的函数递归问题。

总结一下,使用函数递归,要紧盯使函数递归结束的条件,在此条件下,使用return。如果不满足此条件,函数将递归下去。如果最终还是不满足,可以再设置一个返回值。

写的内容有些乱,希望以后自己回顾时还能够看懂。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值