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)]

 

posted @ 2019-04-22 22:01  P-Z-W  阅读(254)  评论(0编辑  收藏  举报