生成器; 推导式

Posted zwq-

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了生成器; 推导式相关的知识,希望对你有一定的参考价值。

一, 生成器
 1,生成器的本质就是迭代器
 2,生成器的特点和迭代器一样.取值方式和迭代器一样(__next__(), send(): 给上一个yield传值).

 3,生成器一般由生成器函数或者生成器表达式来创建
 4,其实就是手写的迭代器

#只要函数内部包含有yield关键字,那么函数名()的到的结果就是生成器,并且不会执行函数内部代码

def func():
    print(====>first)
    yield 1
    print(====>second)
    yield 2
    print(====>third)
    yield 3
    print(====>end)

gen= func()      # 不会执行你的函数. 拿到的是生成器
print(g) # <generator object func at 0x0000000002184360> 
# 函数中如果有yield 这个函数就是生成器函数. 生成器函数() 获取的是生成器. 这个时候不执行函数
# gen.__next__() 执行函数. 执行到下一个yield.
# gen.__next__() 继续执行函数到下一个yield.


    
yield: 相当于return 可以返回数据.
但是yield不会彻底中断函数. 分段执行函数.
可以挂起/保存函数的运行状态


二, 生成器函数
 1, 和普通函数没有区别. 里面有yield的函数就是生成器函数.
 2, 生成器函数在执行的时候. 默认不会执行函数体. 返回生成器
 3,通过生成器的__next__()分段执行这个函数.
 4, send() 给上一个yield传值, 不能再开头(没有上一个yield), 最后一个yield也不可以用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("煎饼果子"))
print(g.send("韭菜盒子"))
print(g.send("锅包肉"))  ## ??

# for i in func(): # for的内部一定有__next__()
# print(i)
#
# print(list(func())) # 内部都有__next__()
 

三, 推导式


 1. 列表推导式 [结果  for循环 条件筛选]
 2. 字典推导式 {k:v for循环 条件筛选}
 3. 集合推导式 {k for循环 条件}


# 推导式: 用一句话来生成一个列表
 lst = ["python"+str(j) for j in range(1,16)]
 print(lst)

# 100以内能被3整除的数的平方
lst = [i*i for i in range(100) if i%3==0]
print(lst)
# [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)
# 集合推导式
lst = [1, 1, 4, 6,7,4,2,2]
s = { el for el in lst }
print(s)

四,生成器表达式


  (结果 for循环 条件)
  特点:
  1. 惰性机制
  2. 只能向前
  3. 节省内存(鸡蛋)

生成器函数
def func():
    print(111)
    yield 222
    yield 333

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

 

重难点:

# 求和
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)   # g = add(n, i) for i in g  所有n都为最后一个元素 10
print(g)  # <generator object <genexpr> at 0x0000000001DF5A40> 还是生产器
# 到最后往里面放数据就对了
print(list(g))  #  [20, 21, 22, 23]   带数据n =10算出 n = 2不带值 
print(list(g)) # []  从源头把数据拿走了这里没有为空

 







































以上是关于生成器; 推导式的主要内容,如果未能解决你的问题,请参考以下文章

推导式

列表推导式和生成器

列表推导式,生成器表达式

推导式

生成器表达式 和 列表推导式

推导式