python06-列表表达式、生成器表达式及其面试题、解耦简单介绍、函数递归相关
小拖拉滴赵某某 人气:1目录:
一、列表推导式
二、生成器表达式
三、集合生成器
四、生成器面试题
五、解耦简单介绍
六、函数递归相关
一、列表推导式
需求:将[1,3,5]中的每个元素平方
正常思路:
1 new_list = [] 2 for i in [1,3,5]: 3 new_list.append(i*i) 4 print(new_list) #输出结果:[1, 9, 25]
列表推导式:以[ ]框住里面的内容
print([i*i for i in [1,3,5]]) #输出结果:[1, 9, 25]
列表推导式图示流程:
可以看出列表推导式的作用就是简化代码
列表推导式例题:
1.输出10以内能被三整除的数的平方
print([i*i for i in range(10) if i %3 == 0]) #[0, 9, 36, 81]
2.输出列表每一个包含‘o’元素的字符串
list_case = [['one','two','three'],['four','five','six']]
正常思路:
1 list_case = [['one','two','three'],['four','five','six']] 2 for i in list_case: 3 for v in i: 4 if v.count('o')>0: 5 print(v)
列表推导式:
list_case = [['one','two','three'],['four','five','six']] print([v for i in list_case for v in i if v.count('o')>0])
二、生成器表达式:
以( )框住里面的内容,就是把列表表达式的[ ]改成( ),就是生成器表达式
例如:
1 case = ('第%d个人' %i for i in range(3))
从生成器中取值的三种方法:
生成器表达式作用:节省内存,简化代码,相比较列表表达式多了一个节省内存的作用,那是因为生成器具有惰性求值的特性
生成一个人生成器归生成,我内存不会加载他,只有当你用的时候我才去加载他。
用户要一个数据,生成器就给一个数据,比如前面例题的range(3),列表表达式就是一下子生成3个,生成器表达式就是你要一个我生成一个。
三、集合生成器:
以{ }框住里面的内容,自带去重功能
lis_case = [-1,1,2,3] print({i*i for i in lis_case}) #输出结果{1, 4, 9}
在以后工作中,列表推导式最常用,但是尽量把列表推导式变成生成器推导式,因为这样节省内存,节省内存的思想应该处处体现在代码里,这样才能体现水平。
四、生成器表达式面试题:
有如下代码:问输出的结果是什么?
1 def demo(): 2 for i in range(4): 3 yield i 4 g=demo() 5 g1=(i for i in g) 6 g2=(i for i in g1) 7 print(list(g1)) 8 print(list(g2))
答案:
[0, 1, 2, 3] []
考点:
内存加载第5行和第6行的时候是不会加载里面的内容的,然后第7行调用g1的时候内存才会去加载g1的内容
g1本质上是一个生成器推导式,只能用一次,所以第7行print一次之后,g1就是空列表了
生成器练习题:问输出结果是啥?
1 def add(n,i): 2 return n+i 3 def test(): 4 for i in range(4): 5 yield i 6 g=test() 7 for n in [1,10,5]: 8 g=(add(n,i) for i in g) 9 print(list(g))
上面的代码可以这样理解:
1 # def add(n,i): 2 # return n+i 3 # def test(): 4 # for i in range(4): 5 # yield i 6 # g=test() 7 # n = 1: 8 # g=(add(n,i) for i in g) 9 # n = 10: 10 # g=(add(n,i) for i in (add(n,i) for i in g)) 11 # n = 5: 12 # g=(add(n,i) for i in (add(n,i) for i in (add(n,i) for i in g))) 13 # print(list(g))
代码解释:
7~12行代码还是会运行,但只是计算 g=什么 ,并不会计算=后面的具体内容,只有后面真正调用g的时候,即(list(g)),这个时候才会回去执行g=后面的内容。
五、解耦简单介绍:
先看一个需求:
写函数,将“从前有座山,山里有个庙,庙里有个老和尚讲故事,讲的什么呀?”打印10遍
一般写法:
def func_case(): for i in range(10):print('从前有座山,山里有个庙,庙里有个老和尚讲故事,讲的什么呀?') func_case()
解耦思想写法:
1 def func_case(): 2 print('从前有座山,山里有个庙,庙里有个老和尚讲故事,讲的什么呀?') 3 for i in range(10): 4 func_case()
这样写的好处就可以在不动第一个函数的情况下,修改打印的次数,一般写法中如果要修改打印次数是直接修改的是函数内部的内容,这样会影响代码质量。
解耦的定义:
要完成一个完整的功能,但这个功能的规模要尽量小,并且和这个功能无关的其他代码应该和这个函数分离
解耦的作用:
1.增强代码的重用性
2.减少代码变更的相互影响
六、函数递归:
递归:一个函数在内部调用自己就叫做递归,递归在函数内部分为递推、回归两个流程,python解释器规定递归层数是有限制的(一般为997层),写递归函数时必须要有一个结束条件。
例如需求:1的年龄比2大两岁,2的年龄比3大两岁,3的年龄比4大两岁,4的年龄是40岁,用函数方式计算1的年龄。
这个需求就是典型的递归问题,下面是代码示例:
1 def age(n): 2 if n == 4 : 3 return 40 4 return age(n+1)+2 5 ret = age(1) 6 print(ret)
代码解释:
递归实例:
用户输入数字n,求n的阶乘:
1 n = int(input(">>>:")) 2 def func(n): 3 if n == 1:return 1 4 return n*func(n-1) 5 print(func(n))
斐波那契:
1 n = int(input(">>>:")) 2 def fib(n): 3 if n == 1 or n == 2:return 1 4 return fib(n-1)+fib(n-2) 5 print(fib(n))
二分法查找索引位置:(需要背过)
1 def search(num,l,start=None,end=None): 2 start = start if start else 0 3 end = end if end else len(l) - 1 4 mid = (end - start)//2 + start 5 if start > end: 6 return None 7 elif l[mid] > num : #17,17 8 return search(num,l,start,mid-1) 9 elif l[mid] < num: 10 return search(num,l,mid+1,end) 11 elif l[mid] == num: 12 return mid 13 l = [2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72,76,82,83,88] 14 print(search(66,l))
三级菜单:
menu = { '北京': { '海淀': { '五道口': { 'soho': {}, '网易': {}, 'google': {} }, '中关村': { '爱奇艺': {}, '汽车之家': {}, 'youku': {}, }, '上地': { '百度': {}, }, }, '昌平': { '沙河': { '老男孩': {}, '北航': {}, }, '天通苑': {}, '回龙观': {}, }, '朝阳': {}, '东城': {}, }, '上海': { '闵行': { "人民广场": { '炸鸡店': {} } }, '闸北': { '火车战': { '携程': {} } }, '浦东': {}, }, '山东': {}, }
1 def Three_Level_Menu(menu): 2 while True: 3 for k in menu:print(k) 4 key = input('>>>(输入q退出,输入b返回上一层):') 5 if key == 'q':return 'q' 6 elif key == 'b':break 7 elif key in menu: 8 ret = Three_Level_Menu(menu[key]) 9 if ret == 'q': return 'q' 10 Three_Level_Menu(menu)
加载全部内容