python note 12 生成器、推导式
1、生成器函数
# 函数中如果有yield 这个函数就是生成器函数. 生成器函数() 获取的是生成器. 这个时候不执行函数
# yield: 相当于return 可以返回数据. 但是yield不会彻底中断函数. 分段执行函数.
# gen.__next__() 执行函数. 执行到下一个yield.
# gen.__next__() 继续执行函数到下一个yield.
不用生成器可能导致内存不够
def order(): lst = [] for i in range(10000): lst.append("衣服"+str(i)) return lst ll = order() print(ll)
使用生成器逐个输出
def order(): for i in range(10000): yield "衣服"+str(i) g = order() # 获取生成器 mingwei = g.__next__() print(mingwei) #输出衣服0 zhaoyining = g.__next__() print(zhaoyining) #输出衣服1
2、send()用法
# send() 和__next__()是一样的. 可以执行到下一个yield, 可以给上一个yield位置传值
def func(): print("我是第一个段") a = yield 123 print(a) print("第二段") b = yield 456 print(b) print("第三段") c = yield 789 print(c) print("最后一个段") yield 79 # 最后收尾一定是yield,否则会报错 g = func() print(g.__next__())#没有上一个yield 所以不能使用send() 开头必须是__next__() print(g.send("煎饼果子"))#赋值给a print(g.__next__()) print(g.__next__()) #我是第一个段 #123 #煎饼果子 #第二段 #456 #None #第三段 #789 #None #最后一个段 #79
def eat(): print("我吃什么啊") a = yield "馒头" print("a=",a) b = yield "鸡蛋灌饼" print("b=",b) c = yield "韭菜盒子" print("c=",c) yield "GAME OVER" gen = eat() # 获取生成器 ret1 = gen. __next__() print(ret1) # 馒头 ret2 = gen.send("胡辣汤") print(ret2) ret3 = gen.send("狗粮") print(ret3) ret4 = gen.send( "猫粮") print(ret4) #我吃什么啊 #馒头 #a= 胡辣汤 #鸡蛋灌饼 #b= 狗粮 #韭菜盒子 #c= 猫粮 #GAME OVER
# for的内部一定有__next__()
def func(): yield 1 yield 13 yield 26 yield 88 yield 46 yield 100 for i in func(): # for的内部一定有__next__() print(i) print(list(func())) # 内部都有__next__()
3、推导式
# 推导式: 用一句话来生成一个列表(列表推导式)
lst = [] for i in range(1, 16): lst.append("python"+str(i)) print(lst) #等同于下列推导式 lst = ["python"+str(j) for j in range(1,16)] print(lst)
# 语法: [结果 for循环 判断]
lst = [i for i in range(100) if i%2==1] print(lst)
# 100以内能被3整除的数的平方
lst = [i*i for i in range(100) if i%3==0] print(lst)
# 寻找名字中带有两个e的人的名字
names = [['Tom', 'Billy', 'Jefferson' , 'Andrew' , 'Wesley' , 'Steven' ,'Joe'], [ 'Alice', 'Jill' , 'Ana', 'Wendy', 'Jennifer', 'Sherry' , 1]] lst = [name for line in names for name in line if type(name) == str and name.count("e") == 2] print(lst)
#for循环写法
names = [['Tom', 'Billy', 'Jefferson' , 'Andrew' , 'Wesley' , 'Steven' ,'Joe'], [ 'Alice', 'Jill' , 'Ana', 'Wendy', 'Jennifer', 'Sherry' , 1]] lst = [] for line in names: for name in line: if name.count("e") == 2: print(name)
#字典推导式
# 语法:{k:v for循环 条件筛选}
# [11,22,33,44] => {0:11,1:22,2:33,3:44} lst = [11,22,33,44] dic = {i:lst[i] for i in range(len(lst)) if i < 2}#字典推导式就一行 print(dic) #输出{0: 11, 1: 22}
dic = {"jj": "林俊杰", "jay": "周杰伦", "zs": "赵四", "ln":"刘能"} d = {v : k for k,v in dic.items()} print(d) #输出{'赵四': 'zs', '刘能': 'ln', '周杰伦': 'jay', '林俊杰': 'jj'}
#集合推导式(可去除重复)
lst = [1, 1, 4, 6,7,4,2,2] s = { el for el in lst } print(s) #输出{1, 2, 4, 6, 7}
4、生成器表达式(多看看)
# 生成器函数 def func(): print(111) yield 222 yield 333 g = func() # 获取生成器 g2 = (i for i in g) # 生成器 g3 = (i for i in g2) # 生成器 print(list(g))#输出111 [222, 333] 源头. 从源头把数据拿走了 print(list(g2))#输出[] 这里执行的时候. 源头已经没有数据 print(list(g3))#输出[] 这里也没有值了
#注意此题思想
# 求和 def add(a, b): return a + b # 生成器函数 # 0-3 def test(): for r_i in range(4): yield r_i # 0,1,2,3 g = test() # 获取生成器 for n in [2, 10]: g = (add(n, i) for i in g) print(list(g)) #输出[20, 21, 22, 23]
5、题目
1.求(x,y)其中x是0-5之间的偶数,y是0-5之间的奇数组成的元祖列表
lst = [(i,j) for i in range(5) for j in range(5) if i%2 ==0 and j %2 ==1] print(lst) #输出[(0, 1), (0, 3), (2, 1), (2, 3), (4, 1), (4, 3)]