python函数 | 生成器

生成器本质上是迭代器,包含__iter__和__next__功能

 

生成器的产生方式:

1,生成器函数构造。

2,生成器推导式构造。

3,数据类型的转化。

 

通过构造生成器函数,就是将函数return变为yield

def func2(x):
    x += 1
    print(111)
    yield x

    x += 1
    print(222)
    yield x

func2(2)                #函数不会执行
g_obj  =func2(3)          #将func2(3)赋值给g_obj,g_obj是个迭代器
g_obj.__next__()          #输出结果是111,一个next对一个一个yield,只有遇到next,函数才会执行
print(g_obj.__next__())    #输出结果是222   \n    5
print(g_obj.__next__())    #超出,将报错
def func1():
    for i in range(10):
        yield i

g=func1()
for i in range(10):
    print(g.__next__())         #打印0-9,一行一个

 

return 与 yield的区别

① 自定制的区别

② 内存级别的区别

     迭代器是需要可迭代对象进行转化,可迭代对象非常占内存

     生成器是直接转化,从本质上节省内存

 

 next 和send 功能一样,都是执行一次

send 与 next 的区别

① send 与 next 一样,也是对生成器进行取值

② send 可以给上一个yield 传值

③ 第一次取值只能用next

④ 最后一个yield永远得不到send传的值

例1

def func1():
    print(1)
    count = yield 1
    print(count)
    print(2)
    count2 = yield 2
    print(count2)
    print(3)
    count3 = yield 3

g=func1()            # g称作生成器对象。
g.__next__()
g.send('alex')
g.send('hello')
输出结果:
1
alex
2
hello
3

例2

def generator():
    print(123)
    content = yield 1
    print('=======',content)
    print(456)
    yield

g = generator()
ret = g.__next__()            # 123
print('***',ret)            # *** 1
ret = g.send('hello')           #send的效果和next一样   ======= hello        \n    456
print('***',ret)            # *** None
执行输出:
123
*** 1
======= hello
456
*** None

send 获取下一个值的效果和next基本一致, 只是在获取下一个值时,给上一yield的位置传递一个数据

 

使用send的注意事项:第一次使用生成器的时候 是用next获取下一个值。最后一个yield不能接受外部的值

例:比如生产10000套服装

 一个厂商直接生产出10000套了

def func1():
    for i in range(1,10001):
        print('ARMAIN服装%d套' % i)
func1() 
执行输出:
...

ARMAIN服装9998套
ARMAIN服装9999套
ARMAIN服装10000套

第二个厂商,先生产出50套,给老板看

def func1():
    for i in range(1,10001):
        yield 'ARMAIN服装%d套' % i

g = func1()
for i in range(1,51):
    print(g.__next__())
执行输出:
...
ARMAIN服装48套
ARMAIN服装49套
ARMAIN服装50套

最终老板只要200套先50套,再150套

def func1():
    for i in range(1,10001):
        yield 'ARMAIN服装%d套' % i

g = func1()
for i in range(1,51):
    print(g.__next__())

#再执行150次,注意,它是从51开始的
for j in range(150):
    print(g.__next__()) 
  • 对于列表而言,for循环是从开始
  • 对于生成器而言,它是有指针的,__next__一次,指针向前一次。它不能从头开始。必须依次执行

 

生成器和迭代器的区别
  迭代器: 有内置方法
  生成器: 开发者自定义

 

问题:什么是生成器?如何写一个生成器?生成器怎么取值?

生成器,即生成一个容器。在Python中,一边循环,一边计算的机制,称为生成器。

生成器示例

def fun1():
    yield 1

 

生成器使用__next__()方法取值,或者for循环

你可能感兴趣的:(python函数 | 生成器)