day8-基础函数的学习(三)
开始今日份总结
今日目录
1.生成器
2.列表推导式
3.匿名函数
4.装饰器
开始今日份总结
1.生成器
1.1 生成器的定义
定义:生成器本质就是迭代器,生成器是自己用python代码写的迭代器
1.1.1 生成器函数
def func(): yield 666 yield '三包春药' ret = func() #函数中含有yield这个关键字参数就是一个生成器函数 print(next(ret)) print(next(ret)) print(next(ret)) #一个next对应一个yield,如果输入多的next则报错 #StopIteration错误
对于yield与return之间的差别
- 俩者都会返回值,return是给函数的执行者返回值,yield是给next()返回值
- 碰到return会结束函数,yield只会冻结函数,有一个next唤醒输出
1.1.2 生成器的用法
现在有一个需求:商家需要500个搪瓷杯,找甲乙俩家生产搪瓷杯,甲一次性备料,一次性生产完毕,乙根据生产需求,提了需求,然后生产一部分
甲厂
def glass(): for i in range(500): print('%s号杯子'%i) glass()
乙厂
def glass2(): for i in range(500): yield '%s号杯子'%i obj = glass2() for i in range(100): print(next(obj)) for j in range(20): print(next(obj)) #可以分批,根据订单来生产商品,第一批100,第二批20
通过上面我们可以得知生成器的特点
- 节省内存,需要一个你产生一个
- 惰性机制,只有调用时才运行
- 一条道走到黑,只会一直往下走,不会返回
1.2 send的用法
send的用法,不止能对应yield传值,也可以给上一个yield发送一个值
def func(): msg1 =yield '111' print(msg1) msg2 = yield 'abc' print(msg2) yield [12,13,14] genor = func() print(genor.send(None)) print(genor.send('ABC')) print(genor.send(333)) #结果 111 ABC abc 333 [12, 13, 14] #例外情况一:第一个send不为空 报错:can't send non-None value to a just-started generator 谨记send是对上一个yield赋值 #例外情况二:在最后一个位置多输入一个send 报错:StopIteration 谨记send和和yield是一一对应,多一个就会报这个错误
1.3 yield from的用法
这个是最新的python 3.x的用法
#按照我们的想法应该是迭代的输出test1.test2 .test3. test4 def func(): li =['test1','test2','test3','test4'] yield li obj = func() for i in obj: print(i) #结果 ['test1', 'test2', 'test3', 'test4'] #原因是yield是将li当做是单独的元素返回出来,并不是一个个出来 #为了改善,只能将以下方法 def func(): li =['test1','test2','test3','test4'] yield from li obj = func() for i in obj: print(i) #结果 test1 test2 test3 test4 #yield from是将一个可迭代对象变为迭代器
2.列表推导式
2.1 列表推导式的优点以及常用的三种方法
列表推导式:用一行代码构建简单或者较复杂的列表,还有为了减少代码量,还有最重要的装逼(不知道会不会被打)
2.1.1 循环模式
列表结构: [ 变量(加工后的变量)for 变量 in iterable ]
print([i for i in range(1,101)]) #构建一个列表:['python1期', 'python2期',....'python25期'] l1 = ['python%s期' %i for i in range(1,26)] print(l1) #很简单的构建了一个列表
2.1.2 筛选模式
列表结构:[变量(加工后的变量)for 变量 in interable if 条件]
# 三十以内所有的偶数留到列表中 # print([i for i in range(1,31) if i % 2 == 0]) # 30以内所有能被3整除的数 # print([i for i in range(1,31)if i % 3 == 0]) # 30以内所有能被3整除的数的平方 # print([i**2 for i in range(1,31)if i % 3 == 0]) # ['地球1号', '地球3号','地球5号',....'地球99号',] # print(['地球%s号'% i for i in range(1,100,2)])
2.1.3 三元模式(循环模式)
其实就是带三元运算的循环模式
# 构建一个列表:列表里面的元素是1~20,但是能被3整除元素替换成*。 # ret = '*' if 3>2 else 1 # print(ret) # print(['*' if i % 3 == 0 else i for i in range(1,21)]) # 将至少含有两个e的名字放到一个列表中 # names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'], # ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']] # print([name for l in names for name in l if name.count('e') >= 2])
列表推导式的优缺点
优点:一行搞定,节省代码量,高逼格
缺点:
- 不能用debug模式
- 列表推导式有毒,会盲目去使用列表推导式去写,建议超过三层的不要轻易使用列表推导式
2.2 生成器表达式
与列表推导式基本一模一样,只是[]换成了()
# l1 = ['python%s期' %i for i in range(1,26)] # gentor = ('python%s期' %i for i in range(1,26)) # print(gentor) # for i in gentor: # print(i)
2.3 字典推导式,集合推导式(了解)
# print({i:None for i in range(1,10)}) # mcase = {'a': 10, 'b': 34, 'c': 20, 'd': 15} # print({value:key for key,value in mcase.items()}) # # set1 = {1, -2, 3, -4, 4} # print({i ** 2 for i in set1})
3.匿名函数
def func(x, y): return x + y
# print(func(3,4))
# 针对于只有返回值的这样的函数:python 提供了一个函数可以简化:
# 匿名函数。一行函数
func2 = lambda x,y: x + y
print(func2(3,4))
# 写一个匿名函数:需要三个数字参数,返回值为三个数相乘
4.装饰器
详细内容请看
https://www.cnblogs.com/gbq-dog/p/10222938.html