迭代:可以理解成循环,迭代一次,循环一次
根据所学知识我们知道,直接作用于for循环的数据类型有:
一是集合数据类型,如str , list, tuple, dict, set等
一类是generator,如,生成器和带yield的generator function
这些可以直接作用于for循环的对象统称为可迭代对象 Iterable,(听到可迭代对象可以理解为可用for循环的对象)
可以用isinstance() 判断一个对象是否为Iterable对象:
from collections import Iterable Iterable <class 'collections.abc.Iterable'> # 执行结果 isinstance('abv', Iterable) True # 执行结果 isinstance(1233, Iterable) False # 执行结果
isinstance((i for i in range(10)), Iterable)
True # 执行结果
而生成器不但可以作用于fou循环,还可以被next()不断调用并返回下一个值,知道最后抛出StopIteration错误表示无法继续。
*可以被next()函数调用并不断返回下一个值的对象(东西)叫迭代器:generator
所以生成器只是迭代器的一种,而且不只是生成器可以被next()调用,自己写的一个不是生成器的东西也可以被next()调用。
可以用isinstance() 判断一个对象是否为Iterabor对象:
from collections import Iterator isinstance('abv', Iterator) False # 执行结果 isinstance(1233, Iterator) False # 执行结果 isinstance([], Iterator) False # 执行结果 isinstance({}, Iterator) False # 执行结果 isinstance((i for i in range(10)), Iterator) True # 执行结果
生成器都是Iterabor对象,而list, str, dict 都只是Iterable,而不是 Iterator,把list, str, dict等Iterable变成Iterator,可以使用iter()函数:
isinstance(iter([]), Iterator) True # 执行结果 isinstance(iter({}), Iterator) True # 执行结果
为什么list,dict,str 等不是Iterator,
因为再pyton中,Iterator对象表示的是一个数据流(没有办法判断终点在哪里,无穷尽的,就是说产生这个数据的时候不知道什么时候结束,比如说时间就是一个时间流,而一个列表,字符串都是由一定长度的,字典是有一定大小的),形成一个迭代器的时候,不需要管内容,他会一直往走,没有终止条件。(也就是说如果一个变量是一个迭代器,len一下并不能算出他的长度)Iterator对象可以被next()
函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration
错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()
函数实现按需计算下一个数据,所以Iterator
的计算是惰性的。
Iterator
甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。
总结:
凡是可作用于for
循环的对象都是Iterable
类型;
凡是可作用于next()
函数的对象都是Iterator
类型,它们表示一个惰性计算的序列;
集合数据类型如list
、dict
、str
等是Iterable
但不是Iterator
,不过可以通过iter()
函数获得一个Iterator
对象。
Python3的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