什么是生成器?
生成器可以理解为一种数据类型,这种数据类型自动实现了迭代器协议(其他的数据类型需要调用自己的内置的__iter__方法),所以生成器就是可迭代对象
生成器在python中的表现形式
python中有两种不同的方式提供生成器
1.生成器函数,常规的函数使用return返回结果,生成器函数用yield返回结果。可以返回多次,返回一次后,会记录当前的位置
def testFunc(): yield 1 yield 2 yield 3 x = testFunc() #返回的就是一个生成器 print(x) #打印结果为<generator object testFunc at 0x00000218E16C1C50> print(x.__next__()) #打印结果为1 print(x.__next__()) #打印结果为2
2.生成器表达式,生成器表达式也是一个三元表达式,这里使用一个母鸡下蛋的故事来讲解
(1)不使用生成器的情况,直接给一筐鸡蛋
egg_list= ["鸡蛋%s" %i for i in range(10)] #直接给了10个鸡蛋放在一个列表里 print(egg_list) #打印结果为['鸡蛋0', '鸡蛋1', '鸡蛋2', '鸡蛋3', '鸡蛋4', '鸡蛋5', '鸡蛋6', '鸡蛋7', '鸡蛋8', '鸡蛋9']
这里讲解一下三元表达式,举个更为简单直观的例子,跟C语言的三目运算符很像,下列代码实现了如果名字为CodeScrew
x="ok",否则"x=error"
name = "CodeScrew" x = "OK" if name == "CodeScrew" else "error" print(x) #打印结果为OK
(2)使用生成器的情况,直接给一只老母鸡
laomuji = ("鸡蛋%s" %i for i in range(10)) #直接给了一直老母鸡,老母鸡肚子里有10个鸡蛋 print(laomuji.__next__()) #打印结果为鸡蛋0 print(laomuji.__next__()) #打印结果为鸡蛋1
如果直接给10个鸡蛋,则内存中就得存10个鸡蛋,给老母鸡的话只需要存一只老母鸡,需要蛋的时候再下,节省空间
触发生成器的几种方式
1.直接调用生成器内置的__next__()方法
2.调用系统的next()函数
3.调用生成器内置的send()方法,send的值会传给上次停留的yield
def testFunc(): first = yield 1 print("第一次",first) second = yield 2 print("第二次",second) x = testFunc() #返回的就是一个生成器 print(x) #打印结果为<generator object testFunc at 0x00000218E16C1C50> v1= x.__next__() print(v1) v2= x.send("第一次send") #传给了上次停留的yield 1 那个位置 print(v2) #打印结果为 # 1 # 第一次 第一次send # 2