python3迭代器和可迭代对象_一文读懂 Python3 可迭代对象、迭代器、生成器区别...
笔者学习Python已有一段时间,一直以为对于可迭代对象(iterable)、迭代器(iterator)、生成器(generator)有一定理解了,直到看到《流畅的python》中的讲解才有了更深的体会,话不多说,开始:
对于可迭代对象和迭代器常规的理解:若对象中实现了 __getitem__ 或者 __iter__ 方法,那么这个对象就是可迭代对象
2. 若对象中实现了 __next__ 和 __iter__ 方法,那么这个对象就是迭代器
3. 可迭代对象的背后其实是迭代器在起作用 (后面会说到)
那么什么是可迭代对象,事实上,python中的所有序列集合都是可迭代对象,并且他们都支持for循环遍历。
>>> s = range(4)
>>> for i in s:
print(i)
0
1
2
3
>>> b = list(range(5))
>>> for i in b:
print(b)
0
1
2
3
4
>>> c = {'A':'a', 'B':'b', 'C':'c'}
>>> for key in c:
print(key)
A
B
C
>>> d = set([1,2,3,4])
>>> for i in d:
print(i)
1
2
3
4
为什么他们能够使用for循环遍历元素,背后就是迭代器在起作用,在执行for循环时,可迭代对象通过iter()生成迭代器,然后遍历迭代器中的元素。如果上述代码不使用for想要达到相同的效果可以这样做(用列表举例说明):
>>> a
[0, 1, 2, 3, 4]
>>> iter_a = iter(a)
>>> while 1:
try:
print(next(iter_a))
except StopIteration: # 获取异常
del iter_a
break
0
1
2
3
4
del 作用是废弃当前迭代器对象,因为迭代器对象遍历一次就无法再遍历了,原因是迭代器对象中的__next__方法,当通过next(a)方法(此处a为迭代器对象)依次获取到a中的所有元素,直到输出StopIteration异常。由于上述在for语句中已经对异常进行了处理,所以我们并不会看到,其实每次执行for语句遍历可迭代对象时都生成了一个迭代器,遍历完后就废弃掉。
其次就是在可迭代对象中的__iter__ 方法是实现了一个迭代器。看下面实现了一个数组对象:
#coding:utf-8
class Array():
def __init__(self, maxsize=20): # 指定数组的长度,默认为20
self.maxsize = maxsize
self._items = [None] * maxsize
def __len__(self): # 查看数组长度
return len(self._items)
def __getitem__(self, index):
if index >= self.maxsize: # 索引从0开始
raise Exception('out of the index')
return self._items[index]
def __setitem__(self, index, item):
if index >= self.maxsize: # 索引从0开始
raise Exception('out of the index')
self._items[index] = item
def clear(self):
for i,value in enumerate(self._items):
self._items[i] = None
def __iter__(self):
for item in self._items:
yield item
def append(self,item): # 尾部添加
self._items += [item]
在数组对象中实现了__iter__方法,在此方法中利用yield实现了生成器(生成器和迭代器在一般情况下,没有区别。可以说所有生成器对象都是迭代器对象,有一点细微的区别:生成器对象更倾向于在无限中集合中惰性的输出需要的数据,而迭代器更倾向于在实现已知道所有数据的情况下惰性输出需要的数据,恰当的例子就是斐波那契数列,可以用生成器实现一个斐波那契数列,但因为该数列的元素是无限多个,所以说其是迭代器实现的就没有说由生成器实现的说法恰当)
而在迭代器中也实现了__iter__方法,不过在迭代器中的__iter__方法是实现了如下的内容:
def __iter__(self):
return self
在迭代器对象中的__iter__方法,返回了迭代器本身。这样做的原因是,在需要可迭代对象的地方能够使用迭代器。这个话可能有点绕,不过你想:对于可迭代对象,利用for循环其实利用__iter__方法生成了迭代器;那么如果对于迭代器,利用for循环呢,那么不也是利用__iter__方法生成迭代器吗?但是这里不用生成,因为它本身就是迭代器,所以在迭代器对象中的__iter__方法实现了返回了迭代器本身。
判断一个对象是否是迭代器,可以利用collections库中的abc,它封装了API,比如:
>>> from collections import abc
>>> s = range(9)
>>> isinstance(s, abc.Iterator)
False
>>> f = iter(list(s))
>>> isinstance(f, abc.Iterator)
True
如上,当然你也可以使用next()方法直接看能否输出对象中的元素。不过利用上述的方法能够在程序中合理的区分迭代器和可迭代对象哦。
python3迭代器和可迭代对象_一文读懂 Python3 可迭代对象、迭代器、生成器区别...相关推荐
- python读取枚举_一文读懂Python 枚举
enum是一组绑定到唯一常数值的符号名称,并且具备可迭代性和可比较性的特性.我们可以使用 enum 创建具有良好定义的标识符,而不是直接使用魔法字符串或整数,也便于开发工程师的代码维护. 创建枚举 我 ...
- java中date类型如何赋值_一文读懂java中的Reference和引用类型
简介 java中有值类型也有引用类型,引用类型一般是针对于java中对象来说的,今天介绍一下java中的引用类型.java为引用类型专门定义了一个类叫做Reference.Reference是跟jav ...
- mysql 默认事务隔离级别_一文读懂MySQL的事务隔离级别及MVCC机制
回顾前文: <一文学会MySQL的explain工具> <一文读懂MySQL的索引结构及查询优化> (同时再次强调,这几篇关于MySQL的探究都是基于5.7版本,相关总结与结论 ...
- psm倾向得分匹配法举例_一文读懂倾向得分匹配法(PSM)举例及stata实现(一)
原标题:一文读懂倾向得分匹配法(PSM)举例及stata实现(一) 一.倾向匹配得分应用之培训对工资的效应 政策背景:国家支持工作示范项目( National Supported Work,NSW ) ...
- odoo pivot中去掉求和_一文读懂深度学习中的卷积运算与图像处理
华为人工智能认证讲师 袁梦 在人工智能深度学习技术中,有一个很重要的概念就是卷积神经网络 CNN(Convolutional Neural Networks).卷积神经网络被广泛地运用到计算机视觉中, ...
- 读懂python语言_一文读懂python反射机制
反射 反射机制就是在运行时,动态的确定对象的类型,并可以通过字符串调用对象属性.方法.导入模块,是一种基于字符串的事件驱动.解释型语言:程序不需要编译,程序在运行时才翻译成机器语言,每执行一次都要翻译 ...
- 一文读懂python3中的所有33个关键字及其用法
学习python,首先需要熟悉一下python的33关键字. 直接上表:(除前三个关键字,其余按字母表顺序排序) False None True and as assert break c ...
- 访问权限冲突定义_一文读懂F5 REST API的细粒度角色访问控制
↑ 点击上方"小咩社长"关注我 阅读提示|本文大概4718字 阅读需要12分钟 写在前面: 前两天一个保险的客户联系我说有个需求,问通过调用F5 REST API可否实现?: ...
- networkx edge 属性_一文读懂Python复杂网络分析库networkx | CSDN博文精选
作者 | yyl424525 来源 | CSDN博客 文章目录 1. 简介 安装 支持四种图 绘制网络图基本流程 2. Graph-无向图 节点 边 属性 有向图和无向图互转 3. DiGraph-有 ...
最新文章
- ACMNO.49:一元三次方程求解(主要就是精度问题)
- Android --- 夜神模拟器中没有图片怎么办?夜神模拟器中怎么导入图片?
- python 零代码快速开发平台_现在低代码开发平台和零代码平台区别是什么?
- 【perl】simpleHTTP
- 吉比特java开发_JVM 吉比特后台 Java 开发实习生 20 分钟一轮游 _好机友
- PyMongo官方文档翻译——VNPY
- JavaScript机器学习之KNN算法
- 正则表达式(面试会考)
- 使用XAMPP轻松建站(上)
- SpringBoot之注解
- for循环中取出最大最小 累加_使用 for 循环实现从 1 累加至 10。_学小易找答案...
- 编译linux内核成vmlinuz,内核编译之vmlinuz vmlinux system.map initrd
- 随书光盘资源下载/提取码(二)
- iOS 健康 计步 卡路里
- 计算机网络验证性实践
- (三万字长文)面试redis缓存大全!
- Mac电脑为什么适合编程?
- 开关电源环路的零极点可以在反馈端补偿吗_开关电源的建模和环路补偿设计(1):小信号建模的基本概念和方法(一)...
- 《数据库原理》实验 西北工业大学
- 笔记本电脑屏幕当作扩展屏幕(一台PC给另一台PC当扩展屏 win10自带功能)
热门文章
- Myeclipse的使用方法-添加,修改,删除JRE,修改项目中的jre不显示问题
- ContextLoaderListener的用途以及配置方式
- Linux 常见命令之Find \; +结合其它命令使用案例详解
- 处理时间_5_计算时间列所在年的周序号
- 处理字符串_3_处理含引号的字符串
- kill linux 信号量,kill用法详细解释(特别是信号量9的使用以及理解)
- mysql 体系结构不匹配_指定的DSN包含驱动程序和应用程序之间的体系结构不匹配...
- python 数据类型 、运算符
- 【短信插件】短信如何对接74cms_v4.2.66_骑士人才系统
- 开平推进智慧城市等领域信息化建设及公共数据资源共享