python tips:迭代器与可迭代对象
for循环
for i in s:
print(i)
在上述for循环中,不断地将s中的值赋值给i,然后打印出来。这种只针对s中元素的循环称为对s的迭代,能够迭代的s称为可迭代的。
python为了实现for循环,需要迭代的对象实现迭代协议或序列协议,以获取一个迭代器。下面只讨论迭代协议,即实现一个预定义的方法:
__iter__(self):返回一个迭代器
for在对对象进行迭代时,会调用对象的__iter__方法构造一个迭代器,然后对该迭代器进行迭代,迭代过程就是不断调用迭代器的方法获取元素:
__next__(self):返回下一个元素,迭代完成抛出stopIteration异常
定义上,实现了上述两个方法的对象称作迭代器。
从理论上讲__iter__方法只要返回一个包含__next__方法的对象就行了,不一定要是迭代器。
这里需要区分迭代器和可迭代对象,迭代器是实现了__iter__和__next__方法的对象,它一定是可迭代对象。而可迭代对象不一定是迭代器,实现了__iter__方法就是可迭代对象。
列表、元组、字符串、字典等对象只实现了__iter__方法,所以它们是可迭代对象,而不是迭代器。
列表不是迭代器
class A:
def __iter__(self):
return [1, 2, 3, 4, 5] class B:
def __iter__(self):
return [1, 2, 3, 4, 5].__iter__() try:
for a in A():
print(a)
except Exception as e:
print(e) for b in B():
print(b)
输出结果
iter() returned non-iterator of type 'list'
1
2
3
4
5
__iter__方法一定要返回迭代器,而列表虽然是可迭代对象,但不是迭代器,所以会抛出异常。显式调用列表的__iter__方法返回一个迭代器即可正常运行。
__iter__返回的对象实现了__next__就可以正常迭代
class A:
def __iter__(self):
return B() class B:
def __init__(self):
self.i = 0
self.n = 5
def __next__(self):
if self.i < self.n:
self.i += 1
return self.i
raise StopIteration for i in A():
print(i)
输出结果
1
2
3
4
5
for循环对A的实例进行迭代,__iter__返回了B的实例,它没有__iter__方法,所以不是迭代器,但是可以正常迭代。
使用序列协议的for循环
class A:
def __init__(self):
self.array = [1, 2, 3, 4, 5] def __getitem__(self, i):
return self.array[i] for i in A():
print(i)
输出结果
1
2
3
4
5
上述代码实现序号从0开始的__getitem__方法,即实现了序列协议,于是for循环能够从实现序列协议的对象中构造一个迭代器用于迭代。
for循环获取迭代器的本质是通过内建函数iter,它能够将实现了迭代器协议(主要是__iter__方法)或者序列协议(__getitem__,序号从0开始)的对象转换成生成器。在两种协议都存在的情况下,以迭代器协议为准。
总结:
1. 迭代器是实现了__iter__和__next__方法的对象,可迭代对象实现了__iter__或者实现了序列协议,可在for中进行迭代。列表等对象不是迭代器
2. for循环利用iter函数获取迭代器,之后对迭代器进行迭代
python tips:迭代器与可迭代对象的更多相关文章
- 搞清楚 Python 的迭代器、可迭代对象、生成器
很多伙伴对 Python 的迭代器.可迭代对象.生成器这几个概念有点搞不清楚,我来说说我的理解,希望对需要的朋友有所帮助. 1 迭代器协议 迭代器协议是核心,搞懂了这个,上面的几个概念也就很好理解了. ...
- python之迭代器、可迭代对象、生成器、生成器对象、枚举类型
迭代器 # 迭代器:循环反馈的容器(集合类型)# -- 不同于索引取值,但也可以循环的从容器对象中从前往后逐个返回内部的值# 优点:不依赖索引,完成取值# 缺点:不能计算长度,不能指定位取值(只能从 ...
- 2019-02-02 Python学习——生成器杨辉三角,迭代器与可迭代对象的区别
练习 杨辉三角定义如下: 1 / \ 1 1 / \ / \ 1 2 1 / \ / \ / \ 1 3 3 1 / \ / \ / \ / \ 1 4 6 4 1 / \ / \ / \ / \ / ...
- day11-Python运维开发基础(迭代器与可迭代对象、高阶函数)
1. 迭代器与可迭代对象 # ### 迭代器 """ 迭代器: 能被next方法调用,并且不断返回下一个值的对象,是迭代器(对象) 特征:迭代器会生成惰性序列,它通过计算 ...
- Python迭代器,可迭代对象,生成器
迭代器 迭代器(iterator)有时又称游标(cursor)是程式设计的软件设计模式,可在容器物件(container,例如链表或阵列)上遍访的界面,设计人员无需关心容器物件的内存分配的实现细节. ...
- Python生成器、迭代器、可迭代对象
把一个列表[]改成()就创建了一个生成器:generator,generator保存的是算法. 可以用于for循环的数据类型:1.集合类型:list tuple dict set str2.gener ...
- Python 中 Iterator(迭代器)和Iterable(迭代对象)的区别
直接可以用作for循环的数据类型有以下几种: tuple.list.dict.str等, 上述数据类型可以用作for循环的叫做可迭代对象Iterable.可以使用isinstance判断一个对象是否是 ...
- Python全栈开发之---迭代器、可迭代对象、生成器
1.什么叫迭代 现在,我们已经获得了一个新线索,有一个叫做“可迭代的”概念. 首先,我们从报错来分析,好像之所以1234不可以for循环,是因为它不可迭代.那么如果“可迭代”,就应该可以被for循环了 ...
- python的生成器与迭代器和可迭代对象
来简单的说下python中的生成器和可迭代对象以及迭代器的问题.只是简单地记录一下并不涉及太深入的内容. 首先来说一下什么是生成器,先看下面的代码: #_*_ coding:utf-8 _*_ res ...
随机推荐
- python库文件路径
python中import语句导入库文件路径可通过sys.path查看.写一个简单的小程序: import sys print sys.path 运行它,本机上得到的结果如下: ['', '/usr/ ...
- 洛谷 P3184 [USACO16DEC]Counting Haybales数草垛
P3184 [USACO16DEC]Counting Haybales数草垛 题目描述 Farmer John has just arranged his NN haybales (1 \leq N ...
- Mac OSX:安装zsh
想在mac下安装oh my zsh,按照https://github.com/robbyrussell/oh-my-zsh上的文档,执行下面这条命令安装:curl -L http://install. ...
- 使用markdown和gitblog搭建自己的博客
GitBlog官网 GitBlog文档 Gitblog官方QQ群:84692078 GitBlog是一个简单易用的Markdown博客系统.它不须要数据库,没有管理后台功能,更新博客仅仅须要加入你写好 ...
- java读取中文分词工具(一)
import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.I ...
- Git 主要的工作流程
Git使用个进制字符的SHA- Hash来唯一标识对象 如:e98757d0598ab6eeaf1df0d87dd00826048bd80b git 有种对象 1.blob 表示文本文件,二进制文件或 ...
- 架构师速成5.1-小学gtd进阶
人生没有理想,那和咸鱼有什么差别. 有了理想怎样去实现.这就是gtd须要解决的问题.简单说一下gtd怎么做? 确定你的目标.假设不能确定长期目标,至少须要一个2年到3年的目标. 目标必须是能够衡量的, ...
- 使用同步适配器(sync adapter)数据传输
在android设备与webserver之间实现数据同步能显著提高你的应用的有用性.让你的应用更受用户的欢迎. 比方说.你的数据上传给webserver,这就有了一个有用的备份.当用户的设备离线工作时 ...
- Java-MyBatis:MyBatis
ylbtech-Java-MyBatis:MyBatis 1.返回顶部 1. MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foun ...
- git使用简易指南(转)
创建新仓库 创建新文件夹,打开,然后执行 git init以创建新的 git 仓库. 检出仓库 执行如下命令以创建一个本地仓库的克隆版本:git clone /path/to/repository 如 ...