一篇文章弄懂Python中的可迭代对象、迭代器和生成器

我们都知道,序列可以迭代。但是,你知道为什么吗? 本文来探讨一下迭代背后的原理。

序列可以迭代的原因:iter 函数。解释器需要迭代对象 x 时,会自动调用 iter(x)。内置的 iter 函数有以下作用:

(1) 检查对象是否实现了 iter 方法,如果实现了就调用它,获取一个迭代器。

(2) 如果没有实现 iter 方法,但是实现了 getitem 方法,而且其参数是从零开始的索引,Python 会创建一个迭代器,尝试按顺序(从索引 0 开始)获取元素。

(3) 如果前面两步都失败,Python 抛出 TypeError 异常,通常会提示“C objectis not iterable”(C 对象不可迭代),其中 C 是目标对象所属的类。

由此我们可以明确知道什么是 可迭代的对象: 使用 iter 内置函数可以获取迭代器的对象。即要么对象实现了能返回迭代器的 iter 方法,要么对象实现了 getitem 方法,而且其参数是从零开始的索引。

下面看一个实现了getitem方法的例子:

输出结果:

我们创建了一个类Eg1,并且为这个类实现了 getitem 方法, 它的实例化对象o1 就是可迭代对象。

下面我们看一个实现 iter 方法的例子,因为用到了迭代器,所以在此我们必须在明确一下迭代器的用法。 标准的迭代器接口有两个方法:

返回下一个可用的元素,如果没有元素了,抛出 StopIteration异常。

返回 self,以便在应该使用可迭代对象的地方使用迭代器,例如在 for 循环中。

我们创建了Eg2类,并为它实现了 iter 方法,此方法返回一个迭代器Eg2Iterator。 Eg2Iterator 实现了我们之前所说的next和iter方法。 实例化对象,并循环输出:

可见,和o1是一样的。

我们通过两种方法实现了一个自己的可迭代对象,再此过程中我们要明确可迭代的对象和迭代器之间的关系:

Python 从可迭代的对象中获取迭代器。

iter方法从我们自己创建的迭代器类中获取迭代器,而getitem方法是python内部自动创建迭代器。

至此,我们明白了如何正确地实现可迭代对象,并且引出了怎样实现迭代器,但是使用迭代器方法(即上面的例子2)的代码量有点大,下面我们来了解一下如何使用更符合 Python 习惯的方式实现 Eg2类。

哦了!就这么简单优雅!不用再单独定义一个迭代器类!

这里我们使用了yield 关键字, 只要 Python 函数的定义体中有 yield 关键字,该函数就是生成器函数。调用生成器函数时,会返回一个生成器对象。也就是说,生成器函数是生成器工厂。 当然,例子3的代码还可以使用yield from进一步简化:

到这里我们明白了 可迭代对象 和 迭代器,还引申出了生成器,但还有一点没有提,那就是生成器表达式。

使用生成器表达式例子4的代码可以修改为:

在python中,所有生成器都是迭代器。

最后,总结一下:

(1)什么是可迭代对象? 可迭代对象要么实现了能返回迭代器的 iter 方法,要么实现了 getitem 方法而且其参数是从零开始的索引。

(2)什么是迭代器? 迭代器是这样的对象:实现了无参数的 next 方法,返回下一个元素,如果没有元素了,那么抛出 StopIteration 异常;并且实现iter 方法,返回迭代器本身。

(3)什么是生成器? 生成器是带有 yield 关键字的函数。调用生成器函数时,会返回一个生成器对象。

(4)什么是生成器表达式? 生成器表达式是创建生成器的简洁句法,这样无需先定义函数再调用。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对我们的支持。

时间: 2019-08-11

python使用生成器实现可迭代对象

本文实例为大家分享了python使用生成器实现可迭代对象的具体代码,供大家参考,具体内容如下 案例分析: 实一个可迭代对象的类,它能迭代出给定范围内所有的素数: pn = Number(1, 30) for k in pn: print(k) 结果为:2,3,5,7,11,13,17,19,23,29 如何解决这个问题? 将该类的__iter__方法实现成生成器函数,每次yield返回一个素数 #!/usr/bin/python3 class Number(object): def __init

详解Python中的内建函数,可迭代对象,迭代器

Python中的内建函数和可迭代对象,迭代器 求值标识 id() #标识id 返回对象的唯一标识,CPython返回内存地址 hash() #哈希, 返回对象的哈希值 len(s) -->返回一个集合类型的元素个数 range(start,stop[,step]) -->返回一个从start开始到stop结束,步长为step的可迭代对象.step默认为1 类型判断 type() #返回对象的类型 isinstance(obj,class_or_tuple) ->True|False #判

Python cookbook(数据结构与算法)从任意长度的可迭代对象中分解元素操作示例

本文实例讲述了python从任意长度的可迭代对象中分解元素操作.分享给大家供大家参考,具体如下: 从某个可迭代对象中分解出N个元素,但是可迭代对象的长度可能超过N,会出现"分解值过多"的异常: 使用"*表达式"来解决该问题: Python 3.4.3 (v3.4.3:9b73f1c3e601, Feb 24 2015, 22:43:06) [MSC v.1600 32 bit (Intel)] on win32 Type "copyright",

Python可迭代对象操作示例

本文实例讲述了Python可迭代对象.分享给大家供大家参考,具体如下: 1.列表生成式 list = [result for x in range(m, n)] g1 = (i for i in range(101)) print(type(g1)) print(g1) print(g1.__next__()) 输出: <class 'generator'> <generator object <genexpr> at 0x0000024E6AC08F10> 0 g1

python生成器,可迭代对象,迭代器区别和联系

生成器,可迭代对象,迭代器之间究竟是什么关系? 用一幅图来概括: 1.生成器 定义生成器 方式一: //区别于列表生成式 gen = [x*x for x in range(5)] gen = (x*x for x in range(5)) print(gen) //Out:<generator object <genexpr> at 0x00000258DC5CD8E0> 方式二: def fib(): prev, curr = 0, 1 while True: yield cu

ES6 迭代器与可迭代对象的实现

ES6 新的数组方法.集合.for-of 循环.展开运算符(...)甚至异步编程都依赖于迭代器(Iterator )实现.本文会详解 ES6 的迭代器与生成器,并进一步挖掘可迭代对象的内部原理与使用方法 一.迭代器的原理 在编程语言中处理数组或集合时,使用循环语句必须要初始化一个变量记录迭代位置,而程序化地使用迭代器可以简化这种数据操作 如何设计一个迭代器呢? 迭代器的本身是一个对象,这个对象有 next( ) 方法返回结果对象,这个结果对象有下一个返回值 value.迭代完成布尔值 done,

浅谈Python中的可迭代对象、迭代器、For循环工作机制、生成器

1.iterable iterator区别 要了解两者区别,先要了解一下迭代器协议: 迭代器协议是指:对象需要提供__next__()方法,它返回迭代中的元素,在没有更多元素后,抛出StopIteration异常,终止迭代. 可迭代对象就是:实现了迭代器协议的对象. 协议是一种约定,可迭代对象实现迭代器协议,Python的内置工具(如for循环,sum,min,max函数等)通过迭代器协议访问对象,因此,for循环并不需要知道对象具体是什么,只需要知道对象能够实现迭代器协议即可. 迭代器(ite

python中的迭代和可迭代对象代码示例

什么是迭代(iteration)呢? 给定一个list或者tuple,通过for循环来遍历这个list或者tuple.这种遍历就是迭代(iteration).只要是可迭代的对象都可以进行迭代.怎么判断一个对象是否是可迭代的对象呢?可以用collections模块里面的iterable包的isinstance函数进行判断: >>> from collections import Iterable#载入模块 >>> isinstance('abc',Iterable) #字

python中的函数递归和迭代原理解析

这篇文章主要介绍了python中的函数递归和迭代原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 一.递归 1.递归的介绍 什么是递归? 程序调用自身的编程技巧称为递归( recursion).递归做为一种算法在程序设计语言中广泛应用. 一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大

Python中的pygal安装和绘制直方图代码分享

有关pygal的安装,大家可以参阅<pip和pygal的安装实例教程>. 直方图: 直方图是一个特殊的条,它可以取3个数值:纵坐标高度,横坐标开始和横坐标结束. import pygal hist = pygal.Histogram() hist.add('Wide bars', [(5, 0, 10), (4, 5, 13), (2, 0, 15)]) hist.add('Narrow bars', [(10, 1, 2), (12, 4, 4.5), (8, 11, 13)]) hist.

Python中的groupby分组功能的实例代码

pandas中的DataFrame中可以根据某个属性的同一值进行聚合分组,可以选单个属性,也可以选多个属性: 代码示例: import pandas as pd A=pd.DataFrame([['Beijing',1.68,2300,'city','Yes'],['Tianjin',1.13,1293,'city','Yes'],['Shaanxi',20.56,3732,'Province','Yes'],['Hebei',18.77,7185,'Province','No'],['Qing

Python中join()函数多种操作代码实例

这篇文章主要介绍了Python中join()函数多种操作代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 Python中有.join()和os.path.join()两个函数,具体作用如下: . join(): 连接字符串数组.将字符串.元组.列表中的元素以指定的字符(分隔符)连接生成一个新的字符串 os.path.join(): 将多个路径组合后返回 对序列进行操作(分别使用' ' .' - '与':'作为分隔符) a=['1aa','

Python中使用socks5设置全局代理的方法示例

0x01介绍 PySocks使您可以通过SOCKS和HTTP代理服务器发送流量.它是SocksiPy的现代分支,具有错误修复和其他功能. 0x02 安装 λ pip3 install Pysocks 0x03 测试 正常请求,httperror无法获得 加入socks5代理后,可以获得当前程序的全局代理可以 正常访问 import socket import socks socks.set_default_proxy(socks.SOCKS5, "127.0.0.1", 10808)

python中tkinter窗口位置\坐标\大小等实现示例

正在尝试着做一个比较完善的画图软件,计划使用tkinter库中的canvas控件来做,然后正在攻关图形项位置.坐标.大小及其他属性项的保存和加载的问题,刚好需要用到坐标.位置的知识,因此作为这个画图软件的附带产出物,整理成了本篇博文,分享给大家,一起研究研究,期待能对你工作带来启发和帮助. 不忘初心,方得始终,让我们一起共勉! 好的,言归正传,回归本篇博文的主题:python中tkinter窗口位置|坐标\大小等知识的科普. 大家都知道tkinter库中有很多控件和主窗口,因此这些控件和主窗口都

python实现机械分词之逆向最大匹配算法代码示例

逆向最大匹配方法 有正即有负,正向最大匹配算法大家可以参阅http://www.jb51.net/article/127404.htm 逆向最大匹配分词是中文分词基本算法之一,因为是机械切分,所以它也有分词速度快的优点,且逆向最大匹配分词比起正向最大匹配分词更符合人们的语言习惯.逆向最大匹配分词需要在已有词典的基础上,从被处理文档的末端开始匹配扫描,每次取最末端的i个字符(分词所确定的阈值i)作为匹配字段,若匹配失败,则去掉匹配字段最前面的一个字,继续匹配.而且选择的阈值越大,分词越慢,但准确性

java中instanceof与Class的等价性代码示例

本文研究的主要是java中instanceof与Class的等价性的相关问题,具体如下. java 中的instanceof 运算符是用来在运行时指出对象是否是特定类的一个实例.instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例. 实例1(instanceof) 接口Person public interface Person { public void eat(); } 实现类People public class People implements

Hibernate中获取Session的两种方式代码示例

Session:是应用程序与数据库之间的一个会话,是Hibernate运作的中心,持久层操作的基础.对象的生命周期/事务的管理/数据库的存取都与Session息息相关. Session对象是通过SessionFactory构建的,下面举个例子来介绍Hibernate两种获取session的方式. 日志,是编程中很常见的一个关注点.用户在对数据库进行操作的过程需要将这一系列操作记录,以便跟踪数据库的动态.那么一个用户在向数据库插入一条记录的时候,就要向日志文件中记录一条记录,用户的一系列操作都要在