生成器和表达式

1. 生成器
生成器的本质就是迭代器
生成器的特点和迭代器一样.取值方式和迭代器一样(__next__(), send(): 给上一个yield传值).
生成器一般由生成器函数或者生成器表达式来创建
其实就是手写的迭代器

 

 

2. 生成器函数
和普通函数没有区别. 里面有yield的函数就是生成器函数. 

函数中如果有yield 这个函数就是生成器函数. 生成器函数+() 获取的是生成器. 这个时候不执行函数
yield: 相当于return 可以返回数据. 但是yield不会彻底中断函数. 分段执行函数.
gen.__next__() 执行函数. 执行到下一个yield.
gen.__next__() 继续执行函数到下一个yield.
def func():    #这个函数就是一个生成器函数,因为有yield
    print("娃哈哈")
    yield 1     # return和yield都可以返回数据
gen = func() # 不会执行你的函数. 拿到的是生成器
print(gen.__next__())  #先打印"娃哈哈",然后返回1,打印1

生成器函数在执行的时候. 默认不会执行函数体. 返回生成器
通过生成器的__next__()分段执行这个函数.

def order():
    for i in range(10000):
        yield "衣服"+str(i)
g = order() # 获取生成器
amber= g.__next__()
print(amber)    #衣服0
icy= g.__next__()
print(icy)      #衣服1

 

 send() 和__next__()是一样的. 可以执行到下一个yield, 可以给上一个yield位置传值

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("胡辣汤")  #a=胡辣汤      
print(ret2)     #鸡蛋灌饼
ret3 = gen.send("狗粮")   #b=狗粮
print(ret3)     #韭菜盒子
ret4 = gen.send( "猫粮")      #c=猫粮
print(ret4)     #game voer

send() 给上一个yield传值, 不能再开头(没有上一个yield), 最后一个yield也不可以用send(),结尾只能用yield,否则会报错

 def func():
    yield 1
    yield 3
    yield 5
    yield 7
    yield 9
for i in func(): # for的内部一定有__next__()
    print(i)    #1,3,5,7,9

print(list(func())) # 内部都有__next__()    #1,3,5,7,9

 

 

3. 推导式

  用一句话来生成一个列表

lst = ["python"+str(j) for j in range(1,16)]
print(lst)

1. 列表推导式 [结果 for循环 条件筛选]

# 100以内能被3整除的数的平方
lst = [i*i for i in range(100) if i%3==0]
print(lst)

2. 字典推导式 {k:v for循环 条件筛选}

# [11,22,33,44] => {0:11,1:22,2:33}
lst = [11,22,33,44]
dic = {i:lst[i] for i in range(len(lst)) if i < 2} # 字典推导式就一行
print(dic)

3. 集合推导式 {k for循环 条件}  

lst = [1, 1, 4, 6,7,4,2,2]
s = { el for el in lst }    #可去重
print(s)

  

4. 生成器表达式

tu = (i for i in range(10))   # 没有元组推导式(因为元祖不能增加),这是生成器表达式
print(tu) # 生成器 print(tu.__next__())  #0 print(tu.__next__())  #1 print(tu.__next__())  #2 print(tu.__next__())  #3 print(tu.__next__())  #4 print(tu.__next__())  #5

(结果 for循环 条件)
特点:
1. 惰性机制  #没有__next__()就不会取值
2. 只能向前
3. 节省内存(鸡蛋)

def func():
    print(111)
    yield 222
    yield 333
g = func() # 获取生成器
g1 = (i  for i in  g) # 生成器
g3 = func()
g2 = (i  for i in  g3) # 生成器
print(list(g))      # [222,333] 源头. 从源头把数据拿走了
print(list(g1))     #  [] 这里执行的时候. 源头已经没有数 
print(list(g2))     #[222,333],这个是新的g3生成器.

  

 

posted @ 2018-08-13 16:25  amberLIU  阅读(215)  评论(0)    收藏  举报