Python Basic -生成器(generator)

什么是生成器

如下代码所示,列表生成式只是生成了一个列表,并将此列表对象的内存地址赋值给变量。而生成器则是生成一个“generator object”,无论有再多元素都只占用一个很小的空间。当需要使用的时候再行进行计算,而且是计算一个就用一个,用完后即清理相关的内存空间。 这种并不是一次性计算好,而是在使用过程中计算一个用一个的方式就叫生成器(generator).

a = [i for i in range(10)]

print(a)

"""
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
"""
b = (i for i in range(10))

print(b)
"""
<generator object <genexpr> at 0x030D3370>
"""

创建生成器(generator)的方法

  1. 把一个列表生成式的[]改成(),即可创建一个生成器。
  2. 使用“yield”

生成器元素的查看(next())

在python3中,对于生成器有一个内置方法“next()”,用于单次计算元素,计算完成后并使用完成后,从生成器对象中删除,下次再调用“next()”方法时即计算下一个元素,计算完成后并使用。如下如示:

b = (i for i in range(10))

print(b)
"""
<generator object <genexpr> at 0x030D3370>
"""

print(b.__next__()) #计算第一个元素并使用,此处的使用方法是打印
print(b.__next__()) #计算第二个元素并使用,此处的使用方法是打印
print(b.__next__()) #计算第三个元素并使用,此处的使用方法是打印
print(b.__next__()) #计算第四个元素并使用,此处的使用方法是打印
print(b.__next__()) #计算第五个元素并使用,此处的使用方法是打印
"""
<generator object <genexpr> at 0x02D93370>
0
1
2
3
4

"""

如上,并不像列表一样,列表是固定存储在内存中,通过下标可随意调用相应下标的值,而使用“next()”方法调用生成器对象时,调用完,下次不再进行计算。

生成器元素的查看(使用built-in内置函数next())

b = (i for i in range(10))

print(b)
"""
<generator object <genexpr> at 0x030D3370>
"""

print(b.__next__()) #计算第一个元素并使用,此处的使用方法是打印
print(b.__next__()) #计算第二个元素并使用,此处的使用方法是打印
print(next(b)) #计算第三个元素并使用,此处的使用方法是打印
print(next(b)) #计算第四个元素并使用,此处的使用方法是打印
print(next(b)) #计算第五个元素并使用,此处的使用方法是打印
print(next(b)) #计算第六个元素并使用,此处的使用方法是打印
"""
<generator object <genexpr> at 0x00B33370>
0
1
2
3
4
5

"""

next()是python的一个内置函数,而“next()”是生成器对象的一个内置方法。两者并无太大差别,从现象上看并无 差别,而next()是python的内置函数,所以在版本过渡时较平滑。

生成器元素的遍历(for循环)

b = (i for i in range(10))

print(b)
"""
<generator object <genexpr> at 0x030D3370>
"""

for i in b:
    print(i)

"""
<generator object <genexpr> at 0x015A3370>
0
1
2
3
4
5
6
7
8
9

"""

yield 创建生成器

使用yield关键写来创建生成器,创建的格式与定制函数一样,

def generator():
    print("first.")
    yield "OK1"
    print("Secondary.")
    yield "OK2"

firstg = generator()
print(firstg)
"""
<generator object generator at 0x034A18B0>
"""

yield 与 return的区别

Python在函数定义中 使用return用于返回值,且一旦遇到return 函数体就执行完毕;
而生成器generator的函数,在每次使用next()进行调用后遇到yield语句后返回,但是计算并使用完成后会保存当前的位置,下次会再次从yield处进行执行。

next() | __next__()方法计算并使用yield创建的生成器元素

def generator():
    print("first.")
    yield "OK1"
    print("Secondary.")
    yield "OK2"

firstg = generator()
print(firstg)

print(firstg.__next__())
print(firstg.__next__())
"""
<generator object generator at 0x035F1728>
first.
OK1
Secondary.
OK2
"""

send() 向yield中传入相关数据

send()与next() 方法一样,都可以计算并使用数据,但是send()多一个功能就是可以发送一个值给变量。并不是赋值给yield,而是赋值给前面的变量。
第一次进入,并不能直接使用send赋值,可以使用send(None)或者使用next() 先调用计算一次。
需要特别注意的是,send()方法与next()方法一样,会让生成器进行一次计算,并将值返回。且不要以为send只单独只发送一次值,

def generator():
    print("Before.")
    sequence = yield "OK1"
    print(sequence)
    yield "OK2"
#    return None

firstg = generator()
print(firstg)

a = next(firstg)
print(a)

b = firstg.send("This is test value.")

print(b)


"""
<generator object generator at 0x00731798>
Before.
OK1
This is test value.
OK2

"""
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值