前言
使用for循环去遍历序列,但是for循环的效率很低,而且占用了大量的硬件资源。
生成器可以提高for循环遍历效率,而且节省硬件资源。
一、可迭代对象
1、for循环数据类型
(1)集合数据类型,如:list(列表)、tuple(元祖)、dict(字典)、set(集合)、str(字符串)、bytes(字节)等。
(2)生成器(generator),包括生成器和带yield的生成器函数。
2、可迭代对象(Iterable
):直接用于for循环遍历数据的对象。
3、用isinstance()方法判断一个对象是否是
Iterable
对象
>>> from collections import Iterable __main__:1: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working >>> isinstance([],Iterable) True >>> isinstance((),Iterable) True >>> isinstance(100,Iterable) False >>> isinstance('a',Iterable) True
生成器不但可以作用于for循环,还可以被__next__()函数不断调用,并且返回下一个值,直到最后抛出StopIteration
错误表示无法继续返回下一个值而抛出的异常。
二、迭代器
1、定义
迭代器(Iterator
):可以用__next__()函数调用并不断的返回下一个值的对象称为迭代器。
2、用isinstance()方法判断一个对象是否是
Iterator
对象
>>> from collections import Iterator >>> isinstance({},Iterator) False >>> isinstance([],Iterator) False >>> isinstance((i+2 for i in range(5)),Iterator)#生成器 True >>> isinstance('hhsh',Iterator) False
生成器都是Iterator
对象,但是list、dict、str虽然是Iterable
对象,却不是Iterator
对象。
因为python的Iterator
对象表示的是一个数据流,Iterator对象可以被__next__()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration
错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过__next__()函数实现按需计算下一个数据,所以Iterator
的计算是惰性的,只有在需要返回下一个数据时才会计算。
所以Iterator
甚至可以表示一个无限大的数据流,例如:全体自然数。而使用list是永远不可能存储全体自然数的。
3、iter()函数
iter()函数可以
把list、dict、str等Iterable
对象变成Iterator
对象。
>>> isinstance(iter('hhsh'),Iterator) True >>> isinstance(iter({}),Iterator) True >>> isinstance(iter([]),Iterator)
true
4、rang()方法
在python2.7中rang()只是一个list,在python3中是一个迭代器,python2.7中xrange()跟python3中的range()功能是一样的。
>>> range(5) range(0, 5)
运行原理:
x = iter([1,2,3,4,5]) # 首先获得Iterator对象 while True: # 循环 try: i = next(x) # 获得下一个值 except StopIteration: # 遇到StopIteration就退出循环 break
总结
- 凡是可以作用于for循环的对象都是
Iterable
类型。 - 凡是作用于__next__()函数的对象都是
Iterator
类型,它们表示一个惰性计算的序列。 - 集合数据类型,例如:list、dict、str等,是
Iterable
但不是Iterator
- 集合数据类型可以通过
iter
()函数获得一个Iterator
对象。