zoukankan      html  css  js  c++  java
  • 生成器函数

    # ###  生成器函数   
    '''
     (用def定义,里面含有yield)
    # yield 类似于 return
    共同点在于:执行到这句话都会把值返回出去
    不同点在于:yield每次返回时,会记住上次离开时执行的位置 , 下次在调用生成器 , 会从上次执行的位置往下走
    		   而return直接终止函数,每次重头调用.
    yield 6 和 yield(6) 2种写法都可以 yield 6 更像 return 6 的写法 推荐使用
    '''
    from collections import Iterator,Iterable
    
    # (1) 基本使用
    '''如果函数当中包含了yield ,那么这个函数是生成器函数'''
    def mygen():
    	print("one")
    	yield 1
    	print("two")
    	yield 2
    	print("three")
    	yield 3
    
    # 初始化生成器函数  => 返回一个生成器对象 ,简称生成器
    gen = mygen()
    print(isinstance(gen,Iterator))
    # 调用生成器
    res = next(gen)
    print(res)
    res = next(gen)
    print(res)
    res = next(gen)
    print(res)
    # res = next(gen)
    # print(res)
    '''
    代码解析:
    首先初始化生成器函数 返回生成器对象 简称生成器
    同过next进行调用
    
    第一次调用时
    print(one)
    yield 1  记录当前代码执行的位置状态,添加阻塞,暂停在这一行,并返回1,等待下一次调用
    
    第二次调用时候
    print(two)
    yield 2  记录当前代码执行的位置状态,添加阻塞,暂停在这一行,并返回2,等待下一次调用
    
    第三次调用时候
    print(three)
    yield 3  记录当前代码执行的位置状态,添加阻塞,暂停在这一行,并返回3,等待下一次调用
    
    第四次调用时
    因为没有yield 返回值了 所以直接报错....
    '''
    
    
    # (2) 优化代码
    def mygen():
    	for i in range(1,101):
    		yield "我的球衣号码是%d" % (i)
    
    # 初始化生成器函数 返回 生成器对象 简称生成器
    gen = mygen()
    
    for  i  in range(50):
    	res = next(gen)
    	print(res)
    
    
    for i in range(30):
    	res =  next(gen)
    	print(res)
    
    
    
    # (3) send  把值发送给上一个yield
    '''
    ### send
    # next和send区别:
    	next 只能取值
    	send 不但能取值,还能发送值
    # send注意点:
    	第一个 send 不能给 yield 传值 默认只能写None
    	最后一个yield 接受不到send的发送值
    '''
    
    def mygen():
    	print("start")
    	res = yield 1
    	print(res)
    	
    	res = yield 2
    	print(res)
    	
    	res = yield 3
    	print(res)	
    	print("end")
    
    # 初始化生成器函数 返回生成器
    '''
    send 在第一次调用的时候,必须给参数None gen.send(None) 
    是一个硬性要求的语法(因为第一次调用的时候,没有遇到上一个yield)
    '''
    gen = mygen()
    res = gen.send(None)
    print(res)
    res = gen.send(111)
    print(res)
    res = gen.send(222)
    print(res)
    # res = gen.send(333)
    # print(res)
    '''
    第一次调用时 ,必须使用gen.send(None)
    print(start)
    res = yield 1 记录当前代码执行的位置状态 ,添加阻塞并返回1,等待下一次调用
    
    第二次调用时 ,
    send 先发送 , 在返回 , 发送给yield 1 res接收到了111这个值
    print(111)
    res = yield 2 记录当前代码执行的位置状态 ,添加阻塞并返回2,等待下一次调用
    
    第三次调用时 ,
    send 先发送 , 在返回 , 发送给yield 2 res接收到了222这个值
    print(222)
    res = yield 3 记录当前代码执行的位置状态 ,添加阻塞并返回3,等待下一次调用
    
    第四次调用时,
    因为没有yield 继续返回了 ,直接报错,越界错误
    如果仍然想要执行后面没走完的代码,比如95 96 ,那么要通过try ... except 异常处理来解决
    try:
    	lst = [1,2]
    	print(lst[99])
    except:
    	pass
    '''
    
    ### yield from : 将一个可迭代对象变成一个迭代器返回	
    def mygen():
    	# yield ["陈桂涛","五金玲","张俊林"]
    	yield from ["陈桂涛","五金玲","张俊林"]
    
    # 初始化一个生成器函数mygen  返回生成器
    gen = mygen()
    res = next(gen)
    print(res)
    res = next(gen)
    print(res)
    res = next(gen)
    print(res)
    
    
    # 用生成器写斐波那契数列
    # 1,1,2,3,5,8,13,21.......
    def mygen(n):
    	a = 0 
    	b = 1
    	i = 0
    	while i<n:
    		# print(b)
    		yield b
    		a,b = b,a+b		
    		i+=1
    gen = mygen(100000)
    for  i in range(20):
    	res  = next(gen)
    	print(res)
    
    '''
    a = 0
    b = 1
    a,b = b,a
    '''
    

      

  • 相关阅读:
    List,Set,Map初级学习
    String,StringBuffer,StringBuilder 的使用
    activity跳转
    JSON与List之间的转换
    子线程更新UI
    数据库查询关键字显示所有结果
    Java数据类型转换1
    git 操作
    MySql导出表结构
    springBoot双数据源配置
  • 原文地址:https://www.cnblogs.com/huangjiangyong/p/10908002.html
Copyright © 2011-2022 走看看