三级菜单
这是老师写的代码,自己进行分析:
menu的内容:
menu = { '北京': { '海淀': { '五道口': { 'soho': {}, '网易': {}, 'google': {} }, '中关村': { '爱奇艺': {}, '汽车之家': {}, 'youku': {}, }, '上地': { '百度': {}, }, }, '昌平': { '沙河': { '老男孩': {}, '北航': {}, }, '天通苑': {}, '回龙观': {}, }, '朝阳': {}, '东城': {}, }, '上海': { '闵行': { "人民广场": { '炸鸡店': {} } }, '闸北': { '火车战': { '携程': {} } }, '浦东': {}, }, '山东': {}, }
写一个三级菜单的代码
def threeML(dic): while 1: for k in dic:print(k) key=input('请输入地名:').strip() if key=='b' or key=='q':return key elif key in dic.keys()and dic[key]:#表示输入的这个key在menu中,且这个key的字典不为空 ret=threeML(dic[key])#发生了一次调用 if ret=='q':return 'q' elif (not dic.get(key)) or (not dic[key]): continue threeML(menu)
对这段代码进行分析
第一次调用
#第一次调用 def threeML(dic): while 1: for k in dic:print(k)#这里的执行结果是北京、上海、山东 key=input('请输入地名:').strip()#北京、上海、山东任意输入一个地名,本范例输入北京 if key=='b' or key=='q':return key#如果输入的是b或者q,则返回b或者q,代码结束 elif key in dic.keys()and dic[key]:#表示输入的这个key在menu中,且这个key的字典不为空,北京下面还有子菜单所以不为空,继续执行 ret=threeML(dic[key])#利用递归,发生了第一次调用, if ret=='q':return 'q' elif (not dic.get(key)) or (not dic[key]): continue threeML(menu)
第二次调用
此时key等于北京
则key表示
key={ '海淀': { '五道口': { 'soho': {}, '网易': {}, 'google': {} }, '中关村': { '爱奇艺': {}, '汽车之家': {}, 'youku': {}, }, '上地': { '百度': {}, }, }, '昌平': { '沙河': { '老男孩': {}, '北航': {}, }, '天通苑': {}, '回龙观': {}, }, '朝阳': {}, '东城': {}, }
代码
#第二次调用 def threeML(dic): while 1: for k in dic:print(k)#这里的执行结果是海淀、昌平、朝阳、东城 key=input('请输入地名:').strip()#海淀、昌平、朝阳、东城任意输入一个地名,本范例输入昌平 if key=='b' or key=='q':return key#如果输入的是b或者q,则返回b或者q,代码结束 elif key in dic.keys()and dic[key]:#表示输入的这个key在menu中,且这个key的字典不为空,昌平下面还有子菜单所以不为空,继续执行 ret=threeML(dic[key])#利用递归,发生了调用, if ret=='q':return 'q' elif (not dic.get(key)) or (not dic[key]): continue threeML(menu)
第三次调用
此时key等于昌平
key={ '沙河': { '老男孩': {}, '北航': {}, }, '天通苑': {}, '回龙观': {}, }
#第三次调用 def threeML(dic): while 1: for k in dic:print(k)#这里的执行结果是沙河、天通苑、回龙观 key=input('请输入地名:').strip()#沙河、天通苑、回龙观任意输入一个地名,本范例输入回龙观 if key=='b' or key=='q':return key#如果输入的是b或者q,则返回b或者q,代码结束 elif key in dic.keys()and dic[key]:#由于此时回龙观的下级菜单为空,所以不能执行这段代码 ret=threeML(dic[key]) if ret=='q':return 'q' elif (not dic.get(key)) or (not dic[key]):#此时执行这段代码,由于此时无论是dic.get(key)还是dic[key]的结果都为空,所以其布尔值都为False,not dic.get(key)和not dic[key]就是True,然后执行下一段代码 continue#当上一条利用not将false变为true后,开始执行continue,然后continue跳出当前循环,开始新一轮的while循环 threeML(menu)
此时代码运行过程如下:
def threeML(dic): while 1: for k in dic:print(k)#这里的执行结果仍然是沙河、天通苑、回龙观 key=input('请输入地名:').strip()#沙河、天通苑、回龙观任意输入一个地名,本范例继续输入回龙观则代码会陷入死循环 if key=='b' or key=='q':return key#如果输入的是b或者q,则返回b或者q,结束本次代码,同时将b或者q返回给第三次调用(递归函数的原理) elif key in dic.keys()and dic[key]: ret=threeML(dic[key]) if ret=='q':return 'q' elif (not dic.get(key)) or (not dic[key]): continue threeML(menu)
当将b返回给第三次调用
def threeML(dic): while 1: for k in dic:print(k) key=input('请输入地名:').strip() if key=='b' or key=='q':return key elif key in dic.keys()and dic[key]: ret=threeML(dic[key])#此时ret=b if ret=='q':return 'q'#由于b不等于q,当前的if循环结束,所以又开始了新一轮的while循环,不过此时重新开始海淀、朝阳、东城、昌平的新一轮循环,即返回上一级菜单 elif (not dic.get(key)) or (not dic[key]): continue threeML(menu)
注意上面的代码不难理解,难点在于b和q,b的作用是返回上一次菜单,q的作用是直接退出
方法二:利用对象进行编程
l=[menu] while l: for key in l[-1]:print(key)#没看明白这里为何是-1 k=input('请输入:').strip() if k in l[-1].keys() and l[-1][k]:l.append(l[-1][k]) elif k=='b':l.pop() elif k=='q':break else:continue
参考:https://www.cnblogs.com/Eva-J/articles/7205734.html#_label4