生成器、生成器函数、推导式、生成器表达式

一、生成器

  生成器的本质就是迭代器

  生成器的特点和迭代器一样。取值方式和迭代器一样(__next__(),send():给上一个yield传值)

  生成器一般由生成器函数或者生成器表达式来创建

  其实就是手写的迭代器

def func():
    print("111")
    yield 222
ret = func()
print(ret)
# <generator object func at 0x0000028F2C062CA8>

  因为函数中存在yield,那么这个函数就是一个生成器函数。这个时候我们在想执行函数就不再是执行函数了,而是获取这个生成器。

def func():
    print("111")
    yield 222
gener = func()  #这个时候函数不会执行,而是获取到生成器
ret = gener.__next__()  #这个时候函数才会执行,yield的作用和return一样也是返回数据
print(ret)
# 111
# 222
def func():
    print("111")
    yield 222
    print("333")
    yield 444
gener = func()
ret = gener.__next__()
print(ret)
ret2 = gener.__next__()
print(ret2)
ret3 = gener.__next__()    #最后一个yield执行完毕,再次__next__()程序报错,也就是说和return无关了
# Traceback (most recent call last):
# 111
# 222
# 333
# 444
#   File "F:/pythonworkspace/day13/day13练习.py", line 52, in <module>
#     ret3 = gener.__next__()
# StopIteration
View Code

  send和__next__()区别:

    1.send和next()都是让生成器想下走一次

    2.send可以给上一个yield的位置传递值,不能给最后一个yield发送值,在第一次执行生成器代码的时候不能使用send(),最后一次也不能使用。

二、生成器函数

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

  生成器函数在执行的时候。默认不会执行函数体,返回生成器

  通过生成器的__next__()分段执行这个函数

  send()给上一个yield传值,不能在开头(没有上一个yield),最后一个yield也不可以用send()

三、推导式

  用一句话来生成一个列表

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

  语法:[结果 for循环 判断]

四、生成器表达式

  生成器表达式和列表推导式的语法基本上是一样的。只是把[]替换成()

  生成器表达式和列表推导式的区别:

    1.列表推导式比较耗内存。一次性加载,生成器表达式几乎不占用内存,使用的时候才分配和使用内存。

    2.得到的值不一样,列表推导式得到的是一个列表,生成器表达式获取的是一个生成器。

总结:推导式有,列表推导式,字典推导式,集合推导式,没有元组推导式

   **生成器只有在要值得时候才拿值

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]

 

posted @ 2018-08-13 15:52  被嫌弃的胖子  阅读(133)  评论(0编辑  收藏  举报