博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
迭代器-Iterator
阅读量:5076 次
发布时间:2019-06-12

本文共 2898 字,大约阅读时间需要 9 分钟。

可以直接作用于for循环的数据类型有以下两类

一类是基础数据类型里的str,list,tuple,dict,set

另一类是generator

这些可以直接作用于for循环的对象统称为可迭代对象 Iterable 

可以使用isinstance()判断一个对象是否是Iterable对象:

1 from collections import Iterable 2  3  4 def test_yield(): 5     yield 1 6     yield 2 7  8 print(type([]), isinstance([], Iterable)) 9 print(type(()), isinstance((), Iterable))10 print(type('abc'), isinstance('abc', Iterable))11 print(type({}), isinstance({}, Iterable))12 print(type(100), isinstance(100, Iterable))13 result = test_yield()14 print(type(result), isinstance(result, Iterable))

以下是结果:

1 
True2
True3
True4
True5
False6
True

 

而生成器不但可以作用于for循环,还可以被next()函数不断调用并返回下一个值,直到最后抛出StopIteration错误表示无法继续返回下一个值了。

可以被next()函数调用并不断返回下一个值的对象称为迭代器 Iterator 。

可以使用isinstance()判断一个对象是否是Iterator对象:

1 print(isinstance((x for x in range(10)),Iterator))2 print(type(result), isinstance(result, Iterator))3 print(type([]), isinstance([], Iterator))

以下是运行结果:

1 True2 
True3
False

从上面的结果看,生成器都是Iterator对象,但listdictstr虽然是Iterable,却不是Iterator

可以使用内置函数iter()将list,dict,str,tuple等转化成Iterator print(type(iter([])), isinstance(iter([]), Iterator)) 

 

那为什么list,tuple,dict,str是Iterable,却不是Iterator呢?

这是因为Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。

Python的for循环本质上就是通过不断调用next()函数实现的,

例如对于 number_list = [1, 2, 3, 4, 5] ,下面两段代码是等价的:

1 for item in number_list:2     print(item)
1 it = iter(number_list)2 while True:3     try:4         number = next(it)5         print(number)6     except StopIteration:7         break

 但是我们如果对number_list使用next()方法却会报错:

1 next(number_list)2 TypeError: 'list' object is not an iterator

 

代理迭代

假如我们自定义了一个类,我想直接在这个类的对象进行上执行迭代操作:

1 class Node(object):2     def __init__(self, value):3         self.__value = value4         self.__children = []

实际上我们只需要定义一个 __iter__(self) 方法,将迭代操作代理到类内部的可转化为迭代器的字段上去:

1 class Node(object): 2     def __init__(self, value): 3         self.__value = value 4         self.__children = [] 5  6     def add_child(self, node): 7         self.__children.append(node) 8  9     def set_value(self, value):10         self.__value = value11 12     def get_value(self):13         return self.__value14 15     def __iter__(self):  # __iter__() 方法只是简单的将迭代请求传递给内部的__children    16         return iter(self.__children)

探讨:

Python 的迭代器协议需要__iter__() 方法返回一个实现了__next__() 方法的迭代

器对象。如果你只是迭代遍历其他容器的内容,你无须担心底层是怎样实现的。你所
要做的只是传递迭代请求既可。
这里的iter() 函数的使用简化了代码,iter(s) 只是简单的通过调用
s.__iter__()方法来返回对应的迭代器对象,就跟len(s) 会调用s.__len__()原理
是一样的。

 

小结

-凡是可作用于for循环的对象都是Iterable类型;

-凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;

-集合数据类型如list、dict、str等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。

转载于:https://www.cnblogs.com/z-joshua/p/6370631.html

你可能感兴趣的文章
新手Python第一天(接触)
查看>>
【bzoj1029】[JSOI2007]建筑抢修
查看>>
synchronized
查看>>
codevs 1080 线段树练习
查看>>
[No0000195]NoSQL还是SQL?这一篇讲清楚
查看>>
【深度学习】caffe 中的一些参数介绍
查看>>
Python-Web框架的本质
查看>>
QML学习笔记之一
查看>>
Window 的引导过程
查看>>
App右上角数字
查看>>
从.NET中委托写法的演变谈开去(上):委托与匿名方法
查看>>
小算法
查看>>
201521123024 《java程序设计》 第12周学习总结
查看>>
新作《ASP.NET MVC 5框架揭秘》正式出版
查看>>
IdentityServer4-用EF配置Client(一)
查看>>
WPF中实现多选ComboBox控件
查看>>
读构建之法第四章第十七章有感
查看>>
Windows Phone开发(4):框架和页 转:http://blog.csdn.net/tcjiaan/article/details/7263146
查看>>
Unity3D研究院之打开Activity与调用JAVA代码传递参数(十八)【转】
查看>>
python asyncio 异步实现mongodb数据转xls文件
查看>>