装饰器补充-生成器-函数递归

目录:

一.  上节课补充

二.  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)
 
原文地址:https://www.cnblogs.com/2722127842qq-123/p/12568677.html