python 迭代器

我们已经知道,可以直接作用于for循环的数据类型有以下几种:

一类是集合数据类型,如list、tuple、dict、set、str等;

一类是generator,包括生成器和带yield的generator function。

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

可迭代对象,也就是可循环对象。

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

查看列表

from collections import Iterable
print(isinstance([], Iterable))

执行输出 True

查看数字

print(isinstance(100, Iterable))

执行输出 False

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

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

可以使用isinstance()判断一个对象是否是Iterator器对象,注意,和上面代码不一致!

查看一个对象,是否是迭代器

from collections import Iterator
a = [1,2,3]
b = isinstance((x for x in range(10)), Iterator)
print(a)
print(b)

执行输出

False

True

a虽然是一个列表(可迭代对象),但是它没有next()方法,那么a不是迭代器对象。

生成器都是Iterator对象,但list、dict、str虽然是Iterable,却不是Iterator。

把list、dict、str等Iterable变成Iterator可以使用iter()函数:

from collections import Iterator
print(isinstance(iter([]), Iterator))
print(isinstance(iter('abc'), Iterator))

执行输出

True

True

你可能会问,为什么list、dict、str等数据类型不是Iterator?

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

Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。

小结

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

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

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

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

for x in [1, 2, 3, 4, 5]:
    pass

实际上完全等价于:

# 首先获得Iterator对象:
it = iter([1, 2, 3, 4, 5])
# 循环:
while True:
    try:
        # 获得下一个值:
        x = next(it)
    except StopIteration:
        # 遇到StopIteration就退出循环
        break

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏python学习之旅

Python笔记(十六):迭代器

    iterable对象(可迭代的对象):可以使用for循环,例如:字符串、列表 、字典 、集合等

802
来自专栏前端知识分享

第202天:js---原型与原型链终极详解

JavaScript 中,万物皆对象!但对象也是有区别的。分为普通对象和函数对象,Object 、Function 是 JS 自带的函数对象。下面举例说明

1832
来自专栏机器学习算法与Python学习

Python: 对迭代器的小结

迭代器 迭代器是在python2.2中被加入的,它为类序列对象提供了一个类序列的接口。有了迭代器可以迭代一个不是序列的对象,因为他表现出了序列的行为。当在pyt...

3416
来自专栏coding for love

JS原生引用类型解析3-Function类型

(注1:如果有问题欢迎留言探讨,一起学习!转载请注明出处,喜欢可以点个赞哦!) (注2:更多内容请查看我的目录。)

931
来自专栏ShaoYL

【C语言】指针

5896
来自专栏菩提树下的杨过

ruby学习笔记(2)--类的基本使用

ruby语言跟c#的一些重要差别在于: 1.ruby是动态语言,c#是静态语言--即对象在new出来以后,ruby还可以动态给对象实例添加一些属性或方法(jav...

1896
来自专栏欧阳大哥的轮子

排列组合

对有n个元素的集合S中的其中r个元素进行排列(n >= r)可以用如下几种方法来理解:

871
来自专栏柠檬先生

es6 class

1.Es6引入了Class 类这个概念,作为对象的模板,通过class 关键字,可以定义类。 2.类和模块的内部,默认就是严格模式,所以不需要使用use str...

17310
来自专栏微信公众号:Java团长

Java:类与继承

  对于面向对象的程序设计语言来说,类毫无疑问是其最重要的基础。抽象、封装、继承、多态这四大特性都离不开类,只有存在类,才能体现面向对象编程的特点,今天我们就来...

971
来自专栏北京马哥教育

一文读懂Python可迭代对象、迭代器和生成器

1486

扫码关注云+社区

领取腾讯云代金券