|
def generator(): print(123) yield 1 print(456) yield 2 g = generator() ret = g.__next__() print('***',ret) ret = g.__next__() print('***',ret) ''' 123 *** 1 456 *** 2 '''
1、send
send获取下一个值的效果和next基本一致,只是在获取下一个值的时候,给上一个yield的位置传递一个数据。
使用send的注意项:
(1)第一次使用生成器的时候,是使用next获取第一个值
(2)最后一个yield不能接收外部的值,最后一个yield后面不应该再有代码了。
def generator(): print(123) content = yield 1 print('~~~',content) print(456) yield 2 g = generator() ret = g.__next__() print('***',ret) ret = g.send('hello') # send的效果和next一样 print('***',ret) ''' 123 *** 1 ~~~ hello 456 *** 2 '''
c. 练习题
# 获取移动平均值
def average(): sum = 0 count = 0 avg = 0 while True: num = yield avg sum += num count += 1 avg = sum/count avg_g = average() avg_g.__next__() avg1 = avg_g.send(10) avg1 = avg_g.send(20) print(avg1)
def init(func): # 装饰器————激活函数 def inner(*args,**kwargs): g = func(*args,**kwargs) # g = average() g.__next__() return g return inner @init # average = init(average) =inner def average(): sum = 0 count = 0 avg = 0 while True: num = yield avg sum += num count += 1 avg = sum/count avg_g = average() ret = avg_g.send(10) print(ret) ret = avg_g.send(20) print(ret)
def generator(): a = 'abcde' b = '12345' for i in a: yield i for i in b: yield i g = generator() for i in g: print(i)
改进:
def generator(): a = 'abcde' b = '12345' yield from a #从容器中取的值集体返回 yield from b g = generator() for i in g: print(i)
egg_list=[] for i in range(10): egg_list.append('鸡蛋%s'%i) print(egg_list)
(一)列表推导式,表达比较简洁
格式:值 for循环
egg_list = ['鸡蛋%s'%i for i in range(10)] #列表推导式 print(egg_list)
print([i for i in range(10)]) print([i*i for i in range(10)])
(二)生成器表达式
g = (i for i in range(10)) print(g) for i in g: print(i)
(三)列表推导式和生成器表达式的区别:
1、括号不一样,列表推导式是[],而生成器是()。
2、返回值不一样,列表推导式是一次性把内容全部呈现,而生成器表达式是随用随取,几乎不占用内存。
如:
老母鸡 = ('鸡蛋%s'%i for i in range(10)) # 生成器表达式生成的是一个生成器,需要的时候要一个一个取。 print(老母鸡) for 蛋 in 老母鸡: print(蛋)
g = (i*i for i in range(10)) print(g) for i in g: print(i)
(四)各种推导式
1、列表推导式
(1)[每一个元素或是和元素相关的操作 for 元素 in 可迭代数据类型 if 元素相关的条件] #遍历之后挨个处理
[满足条件的元素相关的操作 for 元素 in 可迭代数据类型 if 元素相关的条件] #筛选功能
# 30以内所有能被3整除的数 ret = [i for i in range(30) if i%3 == 0] # 完整的列表推导式 print(ret) # 30以内所有数的平方 ret = [i**2 for i in range(30) if i%3 == 0] print(ret)
(2)找嵌套列表中名字含有两个e的元素
先for外面的大列表,再for里面的小列表
names = [['Tom','Billy','Jefferson','Andrew', 'Wesley', 'Steven', 'Joe'], ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']] ret = [name for lis in names for name in lis if name.count('e')>=2] print(ret)
(3)列表的生成器表达式
只是把列表推导式的[]换成()
2、字典推导式
例1、将一个字典的key和value对调
mcase = {'a':10, 'b':34} mcase_frequency = {mcase[k]: k for k in mcase} print(mcase_frequency)
例2、合并大小写对应的value值,将k统一成小写
mcase = {'a':10, 'b':34, 'A':7, 'Z':3} mcase_frequency = {k.lower():mcase.get(k.lower(),0) + mcase.get(k.upper(), 0) for k in mcase.keys()} print(mcase_frequency) #列表生成器表达式首先从for 开始看
d={'a':10} print(d.get('b',2)) #若取不到'b'则返回2
3、集合推导式,集合能够自动对结果去重
例 计算列表中每个值的平方
squared = {x**2 for x in [1,-1,2]} print(squared) ''' {1, 4} '''
4、各种推导式(如列表、字典、集合),将[]变成()就成了生成器。
遍历操作
筛选操作
三、本章小节
1、可迭代对象:
拥有__iter__方法
特点:惰性运算,不找它要值的时候,它不工作
数据类型:range、dict、list、set
2、迭代器Iterator
拥有__iter__方法和__next__方法
3、生成器Generator:
本质:迭代器,所以拥有__iter__方法和__next__方法
特点:循环运算 开发者自定义
4、使用生成器
生成器中的数据只能取一次,取完就没了
惰性运算,不找他取值,他就不工作
Archiver|手机版|科学网 ( 京ICP备07017567号-12 )
GMT+8, 2024-5-20 00:57
Powered by ScienceNet.cn
Copyright © 2007- 中国科学报社