1, 生成器的本质就是迭代器
生成器的三种创建办法: (1):通过生成器函数创建 (2)通过生成器表达式创建生成器 (3) 通过数据转换
2,各种推倒式和生成器表达式:
(1): 列表推倒式 如: lis = [结果 for 变量 in 可迭代对象 if 筛选]
lst = ['python%s' % i for i in range(1,15)] print(lst)
lst = [i for i in range(1, 100) if i % 2 == 0 print(lst)
生成器表达式和列表类似: 如: gen = (i for i in range(10)) print(gen) =====> <generator object <genexpr> at 0x106768f10>
gen = (i for i in range(1,100) if i % 3 == 0) 生成器表达式可以直接获取到生成器. 生成器可以直接进行for循环. 生成器具有惰性机制
for num in gen: ======>print(num)
区别: 同样一篮子鸡蛋. 列表推导式: 直接拿到一篮子鸡蛋. 生成器表达式: 拿到一个老母鸡. 需要鸡蛋就给你下鸡蛋.
得到的值不一样. 列表推导式得到的是一个列表. 生成器表达式获取的是一个生成器. 列表推导式耗内存,生成器表达式获取的是一个生成器
(2): 字典推倒式 如: {结果 for 变量 in 可迭代对象 if 筛选} 结果=>key:value
lst1 = ['jay', 'jj', 'sylar'] lst2 = ['周杰伦', '林林俊杰', '邱彦涛'] dic = {lst1[i]: lst2[i] for i in range(len(lst1))} print(dic)
dic = {'a': 1, 'b': '2'} new_dic = {dic[key]: key for key in dic} print(new_dic)
(3): 集合推导式 ( 集合推导式自带去重功能) 注意abs是个内置函数取绝对值的命令,无论正负只取值
如: lst = [1, -1, 8, -8, 12] s = {abs(i) for i in lst} print(s)
(4): 生成器函数
def eat():
print("我吃什什么啊") 注意: yield是分段来执行一个函数,区别于列表推导式优点是节省内存(高价架构师方向)
a = yield "馒头" send和next()都是让生成器向下走一次, send可以给上一个yield的位置传递值
print("a=",a) send不能给最后一个yield发送值. 在第一次执行生成器代码的时候不能使用send()
b = yield "大饼"
print("b=",b)
c = yield "韭菜盒子"
print("c=",c)
yield "GAME OVER" 当程序运行完最后一个yield. 那么后面继续进行__next__()程序会报错
gen = eat() # 获取生成器
ret1 = gen.__next__()
print(ret1)
ret2 = gen.send("胡辣汤") =====> 将 '胡辣汤' 赋值给a
print(ret2)
ret3 = gen.send("狗粮") =====> 将 '狗粮' 赋值给a
print(ret3)
ret4 = gen.send("猫粮") =====> 将 '猫粮' 赋值给a
print(ret4)