一.生成器表达式

生成器本质是迭代器,允许自定义逻辑的迭代器
迭代器和生成器区别:
迭代器本身是系统内置的,重写不了.而生成器是用户自定义的,可以重写迭代逻辑
生成器可以用来钟方式创建:
    (1)生成器表达式(里面是推导式 外面是圆括号)
    (2)生成器函数 (def定义,里面含有yield)
#(1) 生成器表达式 generator
#[1,2,3,4] => [4,8,12,16]
#i<< 2 i乘以2的2次幂
gen = (i<<2 for i in range(1,5))
print(gen)
from collections import Iterable,Iterator
print(isinstance(gen,Iterator))

##(1)使用next进行调用生成器
res = next(gen)
print(res)
res = next(gen)
print(res)
res = next(gen )
print(res)
res = next(gen)
print(res)
#res = next(gen )  #StopIteration
#print(res)        #越界
##(2)使用for循环调用生成器
gen  = (i<<2 for i in range(1,5))
for i in gen:
    print(i)
##(3)for next 搭配调用生成器
gen = (i<<2 for i in range(1,5))
for i in range(2):
    res = next(gen)
    print(res)

二.生成器函数

(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 mygen2():
    for i in range(1,101):
        yield "我的球衣号%d" %(i)

#初始化生成器 返回生成器对象  简称生成器
gen2 = mygen2()

for i in range(50):
    res = next(gen2)
    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])
execpt:
    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(10000)
for i in range(20):
    res = next(gen)
    print(res)

Python 基础之生成器的更多相关文章

  1. 十三. Python基础(13)--生成器进阶

    十三. Python基础(13)--生成器进阶 1 ● send()方法 generator.send(value) Resumes the execution, and "sends&qu ...

  2. 十二. Python基础(12)--生成器

    十二. Python基础(12)--生成器 1 ● 可迭代对象(iterable) An object capable of returning its members one at a time. ...

  3. (转)python基础学习-----生成器和迭代器

    在Python中,很多对象都是可以通过for语句来直接遍历的,例如list.string.dict等等,这些对象都可以被称为可迭代对象.至于说哪些对象是可以被迭代访问的,就要了解一下迭代器相关的知识了 ...

  4. Python基础之生成器

    1.生成器简介 首先请确信,生成器就是一种迭代器.生成器拥有next方法并且行为与迭代器完全相同,这意味着生成器也可以用于Python的for循环中.另外,对于生成器的特殊语法支持使得编写一个生成器比 ...

  5. Python基础 (yield生成器)

    如果在一个函数中使用了yield,那么这个函数实际上生成的是一个生成器函数 ,返回的是一个generator object.生成器是实现迭代的一种方式 特点: 其实返回的就是可以的迭代对象 和迭代的方 ...

  6. python 基础——generate生成器

    通过列表表达式可以直接生成列表,不过列表一旦生成就需要为所有元素分配内存,有时候会很消耗资源. 所以,如果列表元素可以按照某种算法推算出来,这样就不必创建完整的list,从而节省大量的内存空间. 在P ...

  7. python基础(八)生成器,迭代器,装饰器,递归

    生成器 在函数中使用yield关键字就会将一个普通的函数变成一个生成器(generator),普通的函数只能使用return来退出函数,而不执行return之后的代码.而生成器可以使用调用一个next ...

  8. Python基础(生成器)

    二.生成器(可以看做是一种数据类型) 描述: 通过列表生成式,我们可以直接创建一个列表.但是,受到内存限制,列表容量肯定是有限的.而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我 ...

  9. Day12 Python基础之生成器、迭代器(高级函数)(十)

    https://www.cnblogs.com/yuanchenqi/articles/5769491.html 1. 列表生成式 我现在有个需求,看列表[0, 1, 2, 3, 4, 5, 6, 7 ...

  10. python基础之生成器迭代器

    1 生成器: 为什么要有生成器? 就拿列表来说吧,假如我们要创建一个list,这个list要求格式为:[1,4,9,16,25,36……]这么一直持续下去,直到有了一万个元素的时候为止.如果我们要创建 ...

随机推荐

  1. window下进程退出后自动重启

    设计思想:编写批处理脚本监控进程的运行状态,如果发现进程停止,则自动重启该进程.批处理脚本(jk.bat)和进程脚本(hello.bat)如下: 1.jk.bat @echo off rem 定义需监 ...

  2. pip 换源

    pip 换源 pip国内的一些镜像   阿里云 http://mirrors.aliyun.com/pypi/simple/   中国科技大学 https://pypi.mirrors.ustc.ed ...

  3. JS中的Boolean对象

    使用new操作符和Boolean(value)构造函数时,得到的并不是原始的true或false,而是一个对象,JS将对象视为真(true) var oBooleanTrue = new Boolea ...

  4. 《MySQL命令执行过程和存储引擎概述》阅读笔记

    使用MySQL的完整过程: 启动MySQL服务器程序. 启动MySQL客户端程序并连接到服务器程序. 在客户端程序中输入一些命令语句发送到服务器程序,服务器程序收到这些请求后,会根据请求的内容来操作具 ...

  5. 「CQOI2015」任务查询系统

    「CQOI2015」任务查询系统 传送门 好像也是板子题??? 区间修改,单点查询,考虑差分. 然后每次查询时就直接在对应的主席树上二分即可. 参考代码: #include <cstdio> ...

  6. PHP如何实现处理过期或者超时订单的,并还原库存

    订单是我们在日常开发中经常会遇到的一个功能,最近在做一个订单过期与超时的开发.订单过期与超时就不用我解释了吧,其实两者都是同一个问题来着,就是订单未支付的处理,我们要做的是对这些未支付的订单到了一定时 ...

  7. 在工业派上使用opencv库的记录

    1.在工业派linux操作系统环境下,调用OpenCV库,用python写了第一个查看图片的程序 注意:要进入工业派的terminal 参考:https://www.cnblogs.com/magic ...

  8. ubuntu 18 python3.6更换国内源和pip3源

    1.更换国内源 查看Ubuntu18版本和codename(一定要注意codename对应) lsb_release -a No LSB modules are available. Distribu ...

  9. POJ2516 Minimum Cost

    亲爱的,一个货物销售者,现在遇到了一个大问题,他需要你的帮助.在他的销售区域有 N 个店主(从 1 到 N)向他储存货物,Dearboy 有M 个供应点(从 1 到 M),每个供应点提供 K 种不同的 ...

  10. 8个问题看你是否真的懂 JS

    文章转载: https://juejin.im/post/5d2d146bf265da1b9163c5c9#heading-20 原文地址: https://dev.to/aman_singh/so- ...