生成器和推导式
1.生成器和生成器函数
生成器的本质就是迭代器
生成器的获取方式:
1.1 通过生成器函数
1.2 通过生成器表达式创建生成器
1.3 通过数据转换
生成器函数:
函数中包含了yield的就是生成器函数
def func(): print("111") yield 222
ret = func() print(ret)
结果: <generator object func at 0x10567ff68>
生成器函数被执行,获取到的是生成器,而不是函数的执行
取值:
__next__()
def produce(): """生产衣服""" for i in range(1,100001): yield "生产了第%s件衣服"%i
product_g = produce() print(product_g.__next__()) #要一件衣服 print(product_g.__next__()) #再要一件衣服 print(product_g.__next__()) #再要一件衣服
...
# 最后一个yield之后再进行__next__()会报错
# yield 返回值,可以让函数分段执行
send(值) 可以让生成器乡下执行一次,给上一个yiled传一个值,第一个和最后一个不用传值(最后一个传值相当于又向下执行一次,下边没有了,所有会报错)
def func(): print('钢铁侠') a = yield "11" print(a) print("蜘蛛侠") b = yield "22" print(b) print("煎饼侠") c = yield "33" print(c) g = func() print(g.__next__()) print(g.send(1)) print(g.send(2)) print(g.send(3)) # StopIteration
可以for循环
def produce(): """生产衣服""" for i in range(1,100001): yield "生产了第%s件衣服"%i product_g = produce() for i in product_g: print(i)
list() tuple() set()
def func(): yield "钢铁侠" yield "蜘蛛侠" yield "煎饼侠" yield "绿巨人"
g = func() print(list(g))
生成器表达式:(结果 for 变量 in 可迭代对象 if 筛选)
g = (i for i in range(10)) print(list(g)) gen = ("我第%s次爱你" % i for i in range(10)) #拿到内存地址 for i in gen: # 进行for循环拿到结果 print(i) # 生成器表达式也可以进行筛选: # 获取1-100内能被3整除的数 gen = (i for i in range(1, 100) if i % 3 == 0) for num in gen: print(num) # 100以内能被3整除的数的平方 gen = (i * i for i in range(100) if i % 3 == 0) for num in gen: print(num)
生成器表达式和推导式的区别:
1. 推导式比较耗内存. 一次性加载. 生成器表达式几乎不占用内存. 使用的时候才分配和使用内存
2. 得到的值不一样. 推导式得到的是一个结果. 生成器表达式获取的是一个生成器,通过for循环拿结果
深坑==> 生成器. 要值的时候才拿值
2.各种推导式
2.1 列表推导式 [结果 for 变量 in 可迭代对象 if 筛选]
# 生成列表里面装1-1000的数据 lst = [] for i in range(1,1001): lst.append(i) print(lst) # 列表推到式:最终给的是list列表 # 语法 [最终结果(变量)for 变量 in 可迭代对象] lst= [i for i in range(1,1001)] print(lst) # 获取1-100能被3整除的数 lst = [i for i in range(1,101) if i%3 == 0] print(lst) # 100以内被3整除的平方 lst = [i**2 for i in range(1,101) if i%3 ==0 ] print(lst) # 寻找名字中带两个e的人的名字 names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'], ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']] print([name for lst in names for name in lst if name.count('e') == 2])
2.2 字典推导式 {结果 for 变量 in 可迭代对象 if 筛选} 结果=>key:value
dic = {"a":"b","c":"d"} # 把字典中的key:value互换. new_dic = {dic[key]:key for key in dic} # 把循环完的key放到新列表value位置 print(new_dic) lst1 = ["大娃","二娃","三娃","四娃","五娃","六娃","七娃"] lst2 = ['力大无穷','千里眼顺风耳','钢筋铁骨','喷火','喷水','隐身','宝葫芦'] # 把组成一个字典lst1里的元素是key,lst2里的元素是value dic = {lst1[i]:lst2[i] for i in range(len(lst1))} # 索引长度都是一样不需要考虑那么多,只需要循环一个列表就可以了 print(dic)
2.3 集合推导式 {结果 for 变量 in 可迭代对象 if 筛选} 结果=>key
lst = ["马化腾", "马化腾", "王建忠", "张建忠", "张建忠", "张雪峰", "张雪峰"] s = {i for i in lst} # 集合推倒式 print(s) # 集合推导式可以帮我们直接⽣成⼀个集合. 集合的特点: ⽆序, 不重复. 所以集合推导式⾃带去重功能
总结: 推导式有, 列表推导式, 字典推导式, 集合推导式, 没有元组推导式
生成器表达式可以直接获取到生成器对象. 生成器对象可以直接进行for循环.
生成器具有 惰性机制.
def add(a,b): return a+ b def test(): for r_t in range(4): yield r_t g = test() for n in [2,10]: g = (add(n,i)for i in g) print(list(g))
友情提示: 惰性机制, 不到最后不会拿值