day2-2生成器

生成器

生成器,利用迭代器,我们可以在每次迭代获取数据时(通过next()方法)按照特定的规律进行生成。但是我们在实现一个迭代器时,关于当前迭代的状态需要我们自己记录,进而才能根据当前的状态生成下一个数据。为了达到记录当前状态,并配合next()函数进行迭代使用,可以采用更简便的语法。

生成器(generator),生成器是一种特殊的迭代器,它比迭代器更优雅

创建一个生成器

列表[]—>生成器

li=[x**2 for x in range(6)]
print(li)
gen=(x**2 for x in range(6))
print(gen)

print('通过next()函数取得下一个值')
print(next(gen))
print(next(gen))
print(next(gen))
print(next(gen))
print(next(gen))
print(next(gen))
print("通过for遍历")
gen=(x**2 for x in range(6))
for i in gen:
    print(i,end=' ')

生成器函数

在函数中如果出现了yield关键字,那么该函数就不再是一个普通函数而是一个生成器函数。

demo:

def foo():
    yield 1
    yield 2
    # return
    yield 3
f=foo()
print(next(f))#程序会停留在对应yield后的语句
print(next(f))
print(next(f))#当程序遇到return,return后的语句不会再执行。因此报错

next和yield进行匹配。如果遇到return,return后的语句不会再执行。因此报错


def odd():
    n=1
    while True:
        yield  n
        n+=2
odd_num=odd()
print(odd_num)
count=0
for i in odd_num:
    if count>5:
        break
    print(i)
    count+=1
print(next(odd_num))
print(next(odd_num))

1
3
5
7
9
11
15
17

生成器支持的方法

class OddIter:
    def __init__(self):
        self.start=-1
    def __iter__(self):
        return self
    def __next__(self):
        self.start+=2
        return self.start
odd=OddIter()
for i in range(6):
    print(next(odd))
    
print(help(odd))

#运行结果 1,3,5,7,9,11

Help on OddIter in module __main__ object:

class OddIter(builtins.object)
 |  Methods defined here:
 |  
 |  __init__(self)
 |      Initialize self.  See help(type(self)) for accurate signature.
 |  
 |  __iter__(self)
 |  
 |  __next__(self)
 |  
 |  ----------------------------------------------------------------------
 |  Data descriptors defined here:
 |  
 |  __dict__
 |      dictionary for instance variables (if defined)
 |  
 |  __weakref__
 |      list of weak references to the object (if defined)

None

close()


def gen():
    yield 1
    yield 2
    yield 3
    yield 4
    yield 5
g=gen()
print(next(g))
print(next(g))
g.close()
print(next(g)) #回溯

1
Traceback (most recent call last):
2
  File "D:/py/one/o_tr_2生成器.py", line 71, in <module>
    print(next(g)) #回溯
StopIteration
  • send()

  • x=yield y 语句的含义:send()的作用就是使x赋值为其所传送的值(send的参数),然后让生成器执行到下一个yied。

  • 如果生成器未启动,则必须在使用send()前启动生成器,而启动的方法可以是gen.next(),也可以是gen.send(None)执行到第一个yield处。之后就可以使用send(para)不断的传入值了。

  • 如果是已启动,则send(para)的作用就是给x

    赋值发送

#send
def gen():
    value=0
    while True:
        receive=yield value
        if receive=='e':
            break
        value='got: %s'%receive
# receive=yield value 语句的含义:
#send()的作用就是使receive赋值为其所传送的值,然后让生成器执行到下一个yield
g=gen()
print(g.send(None))
print(g.send('aaa'))
print(g.send(123))
print(g.send('e'))

0
Traceback (most recent call last):
got: aaa
got: 123
  File "D:/py/one/o_tr_2生成器.py", line 87, in <module>
    print(g.send('e'))
StopIteration

def gen():
    i=0
    while i<5:
        temp=yield i
        print(i,'+')
        print(temp,'-')
        i+=1
#创建生成器对象
obj=gen()
#使用next()唤醒生成器
print(next(obj),'--')
print(next(obj),'--')
print(next(obj),'--')
print(obj.send('city'),'--')
print(next(obj),'--')

0 –
0 +
None -
1 –
1 +
None -
2 –
2 +
city -
3 –
3 +
None -
4 –

yied的小结

  1. 生成器(generator)能够迭代的关键是他有next()方法,工作原理就是通过重复调用next()方法,直到捕获一个异常。

  2. 带有yield的函数不再是一个普通的函数,而是一个生成器generator,可用于迭代

  3. yield是一个类似return 的关键字,迭代一次遇到yield的时候就返回yield后面或者右面的值。而且下一次迭代的时候,从上一次迭代遇到的yield后面的代码开始执行

  4. yield就是return返回的一个值,并且记住这个返回的位置。下一次迭代就从这个位置开始。

  5. 带有yield的函数不仅仅是只用于for循环,而且可用于某个函数的参数,只要这个函数的参数也允许迭代参数。

6. send()和next()的区别就在于send可传递参数给yield表达式,这时候传递的参数就会作为yield表达式的值,而yield的参数是返回给调用者的值,也就是说send可以强行修改上一个yield表达式值。

  1. send()和next()都有返回值,他们的返回值是当前迭代遇到的yield的时候,yield后面表达式的值,其实就是当前迭代yield后面的参数。

  2. 第一次调用时候必须先next()或send(),否则会报错,send后之所以为None是因为这时候没有上一个yield,所以也可以认为next()等同于send(None)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值