当前位置: 首页 > news >正文

Python迭代器 iterator(iter next) 生成器 generator(yield) yield

迭代器

1、通过iter()方法获得了list的迭代器对象,然后就可以通过next()方法来访问list中的元素了。

   当容器中没有可访问的元素后,next()方法将会抛出一个StopIteration异常终止迭代器。

   字符串,列表或元组对象都可用于创建迭代器

2、迭代器的限制

    不能回到开始

   也无法复制一个迭代器。

   因此要再次进行迭代只能重新生成一个新的迭代器对象。

3、__iter__() 和 __next__() 方法

__iter__() 和 __next__() 方法这两个方法是迭代器最基本的方法:

一个用来获得迭代器对象

一个用来获取容器中的下一个元素

_list = [5,6,7]
it = iter(_list)
print(_list)
print(it)
print(it.__next__())
print(it.__next__())
print(it.__next__())
print(it.__next__()) #此时调用会抛出异常

另一种调用方法

_list = [5,6,7]
it = iter(_list)
print(_list)
print(it)
print(next(it))
print(next(it))
print(next(it))
print(next(it)) #此时调用会抛出异常

遍历迭代器

list_ = [5,6,7]
it = iter(list_)
print(it)
for i,v in enumerate(it):
    print(i,v)

生成器

    在一个函数中,只要有yield。那么这个函数就不再是函数,而成了一个生成器

    生成器的本质就是迭代器,生成器是一种特殊的迭代器

    如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的ist,从而节省大量的内存资源

    在Python中,这种一边循环一边计算的机制,称为生成器(Generator)

    生成器的作用:可以实现多任务(协程-->模拟并发)

    生成器包括两种:生成器函数和生成器表达式

遍历生成器

list(a)

for i in a:
    print(i)

for idx,param in enumerate(net.parameters()):
    print(param)

生成器表达式

将列表解析式[] 改成 () 即可。

g = (x*x for x in range(10))
print(g)
print(next(g))
print(next(g))
print(next(g))
print(next(g))

但是生成器不能通过类来实现

生成器函数

      生成器函数返回数据就不适用return这个关键字了,是用yield

      一个包含yield关键字的函数就是一个生成器函数。(python中yield关键字是区分新老Pythoner的标志之一)

      并且yield不能和return共用,并且yield只能用在函数内

      yield关键字,其作用和return的功能差不多,就是返回一个值给调用者,只不过有yield的函数返回值后函数依然保持调用yield时的状态,当下次调用的时候,在原先的基础上继续执行代码,直到遇到下一个yield或者满足结束条件结束函数为止

(1)生成器函数执行之后会得到一个生成器作为返回值,并不会执行函数体。

(2)执行了__next__()方法之后才会执行函数体,并且获得返回值。

(3)生成器内部支持了生成器协议,不需要明确定义__iter__() 和 __next__()方法

(3)yield和return相同的是可以返回值,但是不同的是yield 不会结束函数

def test():
    yield 1
    yield 2
    yield 3
t = test()

print(next(t))#output:1
print(next(t))#output:1
print(next(t))#output:1
print(next(t))#output:Traceback (most recent call last):StopIteration

       好像并没啥卵用啊!骚年,存在即合理,python有生成器不是没有道理的。数学中有很多算法是无限穷举的(比如自然数),我们不可能一一穷举出来,所以生成器就可以帮助我们。

def foo(num):
    print("starting...")
    while num<10:
        num=num+1
        yield num
for n in foo(0):
    print(n)

理解yield的作用

def fibonacci(n):
    a = 0
    b = 1
    nums = []
    for _ in range(n):
        nums.append(a)
        a,b = b, a+b
    return nums
for i in fibonacci(10):
    print(i)

可以写为

def fibonacci(n):
    a = 0
    b = 1
    for _ in range(n):
        yield a
        a,b = b, a+b
for i in fibonacci(10):
    print(i)

这里的yield表示,每当我们计算出一个元素,就立马将这个元素给送出去。也就是说,外面的for循环就会立即输出这个数。

因此使用yield的好处是,我们并不需要等待整个列表都生成完毕后,再来一个一个的输出。同时也可以节省存储空间。

yield的优势在于一些非常耗时的操作,比如我们可以写一个函数从网络上下载一系列文档,并输出每个文档的内容。如果我们使用yield,则可以保证在一个文档被下载成功后,就立马输出它的内容,而无需等待所有文档都下载完毕。

相关文章:

  • Python协程(generator, yield, send)
  • 虚拟机 虚拟硬盘
  • 8086处理器 硬盘
  • 虚拟机快照
  • 虚拟机克隆 将虚拟机导出为 OVF 格式
  • VMware虚拟机与主机共享文件夹
  • Python异步IO协程 (asyncio)
  • 编译原理 1.1
  • 编译原理1.2
  • 汇编语言的种类
  • Bochs虚拟机 编写主引导扇区程序并执行
  • 编译原理2.1
  • Python 函数式编程(一):高阶函数/函数名变量
  • Pycharm debug
  • MyOS(二):用Java和汇编开发一个helloworld操作系统内核
  • Angular Elements 及其运作原理
  • docker-consul
  • IP路由与转发
  • JavaScript 无符号位移运算符 三个大于号 的使用方法
  • Laravel 实践之路: 数据库迁移与数据填充
  • MYSQL如何对数据进行自动化升级--以如果某数据表存在并且某字段不存在时则执行更新操作为例...
  • node 版本过低
  • springboot_database项目介绍
  • UEditor初始化失败(实例已存在,但视图未渲染出来,单页化)
  • vue+element后台管理系统,从后端获取路由表,并正常渲染
  • vue2.0一起在懵逼的海洋里越陷越深(四)
  • 闭包--闭包作用之保存(一)
  • 好的网址,关于.net 4.0 ,vs 2010
  • 记录一下第一次使用npm
  • 离散点最小(凸)包围边界查找
  • 深度学习在携程攻略社区的应用
  • 王永庆:技术创新改变教育未来
  • 详解NodeJs流之一
  • 一文看透浏览器架构
  • 移动端唤起键盘时取消position:fixed定位
  • 译有关态射的一切
  • 云大使推广中的常见热门问题
  • 这几个编码小技巧将令你 PHP 代码更加简洁
  • ​iOS实时查看App运行日志
  • ​无人机石油管道巡检方案新亮点:灵活准确又高效
  • # Maven错误Error executing Maven
  • # 日期待t_最值得等的SUV奥迪Q9:空间比MPV还大,或搭4.0T,香
  • $.ajax()参数及用法
  • (32位汇编 五)mov/add/sub/and/or/xor/not
  • (4)事件处理——(2)在页面加载的时候执行任务(Performing tasks on page load)...
  • (DFS + 剪枝)【洛谷P1731】 [NOI1999] 生日蛋糕
  • (PWM呼吸灯)合泰开发板HT66F2390-----点灯大师
  • (算法)Game
  • (算法)Travel Information Center
  • (转)利用PHP的debug_backtrace函数,实现PHP文件权限管理、动态加载 【反射】...
  • (转贴)用VML开发工作流设计器 UCML.NET工作流管理系统
  • .CSS-hover 的解释
  • .NET 使用 JustAssembly 比较两个不同版本程序集的 API 变化
  • .NET/C# 获取一个正在运行的进程的命令行参数
  • .net经典笔试题