装饰器补充-生成器-函数递归
目录:
一. 上节课补充
二. yield表达式
三. 三元表达式
四. 生成器
五. 函数的递归
一. 上节课补充
多个装饰器的加载和运行分析
1 def deco1(func1): #func1=warpper2
2 def wrapper1(*args,**kwargs):
3 print('正在运行===>deco1.wrapper1')
4 res1=func1(*args,**kwargs)
5 return res1
6 return wrapper1
7
8 def deco2(func2):#func2=warpper3
9 def wrapper2(*args,**kwargs):
10 print('正在运行===>deco2.wrapper2')
11 res2=func2(*args,**kwargs)
12 return res2
13 return wrapper2
14
15 def deco3(x):
16 def outter3(func3): #func3=index
17 def wrapper3(*args,**kwargs):
18 print('正在运行===>deco3.outter3.wrapper3')
19 res3=func3(*args,**kwargs)
20 return res3
21 return wrapper3
22 return outter3
23 @deco1
24 #@deco1 ==>warpper2=deco1(warpper2) ==>warpper2=warpper1
25 @deco2
26 #@deco2 ==>warpper3=deco2(warpper3) ==>warpper3=warpper2
27 @deco3(111)
28 #deco3(111)=outter3 @outter3==>index = outter3(index)==>index = warpper3
29 #装饰器的加载顺序,从下到上
30 #运行顺序,从上到下
31 def index(x,y):
32 print('from index %s:%s' %(x,y))
二. yield表达式
1. yield表达式基本用法
yield关键字只要出现在函数中,调用这个函数不会执行,会返回一个生成器(自定义迭代器),这里可以对yield传值,在函数内通过一个变量接受这个值
1 def dog(name):
2 print('道哥%s准备吃东西了...' % name)
3 while True:
4 # x拿到的是yield接收到的值
5 x = yield # x = '一根骨头'
6 print('道哥%s吃了 %s' % (name, x))
7
8
9 g = dog('alex')
10
11 g.send(None) # 等同于next(g),先完成初始化
12
13 g.send('一根骨头')
14 # g.send('一根骨头','肉包子') # 不能传2个值,会报错:TypeError: send() takes exactly one argument (2 given)
15 g.send(['一根骨头','肉包子']) # 可以放到列表里传输,列表算是一个值
16 g.send('肉包子')
17 g.send('一桶泔水')
18 # g.close()
19 # g.send('1111') # 关闭之后无法传值
2. 综合应用
1 def dog(name):
2 food_list = []
3 print('大哥%s准备吃东西了...' % name)
4 while True:
5 # x拿到的是yield接收到的值
6 # x = yield 111 # x = ['一根骨头','肉包子']
7 x = yield food_list # x = ['一根骨头','肉包子']
8 print('大哥%s抽了 %s' % (name, x))
9 food_list.append(x)
10
11
12 g = dog('egon')
13
14 res = g.send(None) # 等同于next(g),先完成初始化
15 print(res)
16
17 res = g.send(['一个鞭炮','一根烟'])
18 print(res)
19
20 res = g.send('一个地雷')
21 print(res)
1 def func():
2 print('start...')
3 x = yield 111
4 print('H哈哈')
5 print('H哈哈')
6 print('H哈哈')
7 yield 222
8
9 g = func()
10 res = next(g)
11 print(res)
12
13 res = g.send('xxxx')
14 print(res)
三. 三元表达式
1. 普通的表达式
1 def func(x,y):
2 if x > y:
3 return x
4 else:
5 return y
6
7 res = func(1,2)
8 print(res)
2. 三元表达式
语法格式:条件成立时返回的值 if 条件 else 条件不成立时要返回的值
1 x = 1
2 y = 2
3
4 res = x if x > y else y
5 print(res)
6
7
8
9 Jack = 18
10 Mack = 80
11
12 res = 'Jack是孙子' if Jack < mack else 'mack是爷爷'
13 print(res)
四. 生成器
1. 列表生成式
原代码:
1 l = ['alex_dsb','lxx_dsb','wxx_dsb','xxq','egon_dsb']
2 new_l = []
3 for name in l:
4 if name.endswith('dsb'):
5 new_l.append(name)
改进后:
1 l = ['egon_is_sb','egon_is_dsb','egon_is_superdsb','xxq','egon_dsb']
2
3 new_l = [name for name in l] # 最基础的列表生成式
4 new_l = [name for name in l if name.endswith('sb')]
5
6 print(new_l)
把所有小写字母变成大写
1 l = ['egon_is_sb','egon_is_dsb','egon_is_superdsb','xxq','egon_dsb']
2 new_l = [name.upper() for name in l ]
3 print(new_l)
去掉所有名字的_sb后缀
1 l = ['egon_is_sb','egon_is_sb','egon_is_superd_sb','xxq','egon_sb']
2
3 new_l = [name.replace('_sb','') for name in l]
4 print(new_l)
2. 字典生成式
1 keys = ['name','age','gender'] 2 3 dic = {key:None for key in keys} 4 print(dic) 5 items = [('name','egon'),('age',18),('gender','male')] 6 7 dict = {k:v for k,v in items if k!='gender'} 8 print(dict)
3. 集合生成式
1 keys = ['name','age','gender']
2 set1 = {key for key in keys}
3 print(set1,type(set1))
4. 元组生成式(没有元组生成式)
1 g = (i for i in range(10) if i > 3)
2 print(g,type(g))
3
4 # 输出:<generator object <genexpr> at 0x01D63450> <class 'generator'>
5. 生成器表达式
1 g = (i for i in range(10) if i > 3)
2 # !!!!!!!强调!!!!!!!
3 # 此时g的内部,一个值都没有
4 # 只有next的时候,才会产生一个值
5
6 print(g)
7 print(next(g))
8 print(next(g))
9 print(next(g))
10 print(next(g))
方式一:
1 with open(r'内容.txt',mode='rt',encoding='UTF-8') as f:
2 res = 0
3 for line in f:
4 res += len(line)
5 print(res)
方式二:
1 with open(r'内容.txt',mode='rt',encoding='UTF-8') as f:
2
3 res = sum([len(line) for line in f])
4 print(res)
方式三:效率高
1 with open(r'内容.txt', mode='rt', encoding='UTF-8') as f:
2 # g = (len(line) for line in f)
3 # print(g)
4 # res = sum(g)
5 # print(res)
6 # res = sum((len(line) for line in f))
7 # 上述可以简写为如下格式
8 res = sum(len(line) for line in f)
9 print(res)
五. 函数的递归
1. 递归的定义
函数的递归调用:是函数嵌套调用的一种特殊形式
具体是指:在调用一个函数的过程当中,又直接或者间接地调用到了本身
Python对递归调用循环调用的次数有限制,为1000次
1)调用的例子:
直接调用本身
1 def f1():
2 print('是我')
3 f1()
4
5 f1()
间接调用本身
1 def f1():
2 print('我是f1')
3 f2()
4
5 def f2():
6 print('我是f12')
7 f1()
8
9 f1()
2)一段代码的循环运行方案有2种
方式1:while、for循环
1 while True:
2 print(111)
3 print(222)
4 print(333)
方式2:while、for循环
1 def f1():递归的本质,就是循环
2 print(111)
3 print(222)
4 print(333)
5 f1()
6
7 f1
2. 需要强调的一点是:
Python没有尾递归优化(了解)
递归调用不应该无限地调用下去,必须在满足某种条件下,结束递归
1 n = 0
2 while n < 10:
3 print(n)
4 n += 1
5 def func(n):
6 if n == 10:
7 return
8 print(n)
9 n += 1
10 func(n)
11
12 func(0)
3. 递归的2个阶段
1.回溯:一层一层调用下去
2.递推:满足某种结束条件,结束递归调用,然后一层一层返回
1 # age(5) = age(4) + 10
2 # age(4) = age(3) + 10
3 # age(3) = age(2) + 10
4 # age(2) = age(1) + 10
5 # age(1) = 18
6 def age(n):
7 if n == 1:
8 return 18
9
10 return age(n-1) + 10
11
12 res = age(5)
13 print(res)
4. 递归的应用
1 l = [1, 2, [3, [4, [5, [6, [7, [8, [9, 10, 11]]]]]]]]
2 # l = [1,2,[3,4]]
3 def f1(list1):
4 for x in list1:
5 if type(x) is list:
6 # 如果是列表,应该再循环、再判断,即 重新运行本身的代码
7 f1(x)
8 # for a in x:
9 # if type(a) is list:
10 # pass
11 # else:
12 # print(a)
13 else:
14 print(x)
15
16 f1(l)