因学识经验有限,如有不正之处望读者指正,不胜感激;也望借此平台留下学习笔记以温故而知新。这一篇博客是Python基础之迭代器,借此梳理下,希望对您有所帮助。
可以直接作用于for循环的数据类型有以下几种:
一类是集合数据类型,如list,tuple,dict,set,str等
一类是generator ,包括生成器和带yeild的generator function
这些可以 直接作用于for循环的对象统称为可迭代对象:Iterable
可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator
a = [i for i in range(10)]
next(a)
结果返回:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
in
1 a = [i for i in range(10)]
----> 2 next(a)
TypeError: 'list' object is not an iterator
list,dict,str虽然是Iterable,却不是Iterator
from collections import Iterator
from collections import Iterable
print(isinstance(a,Iterator))
print(isinstance(a,Iterable))
print(isinstance({},Iterable))
print(isinstance('abc',Iterable))
结果返回如下:
False
True
True
True
iter(iterable)#一个参数,要求参数为可迭代的类型
把list、dict、str等Iterable变成Iterator可以使用iter()函数:
print(isinstance({},Iterator))
print(isinstance('abc',Iterator))
print(isinstance(iter({}),Iterator))
print(isinstance(iter('abc'),Iterator))
结果返回如下:
False
False
True
True
为什么list、dict、str等数据类型不是Iterator?
这是因为Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。
Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。
小结
Python的for循环本质上就是通过不断调用next()函数实现的,例如:
x = [1,2,3]
for i in x:
print(i)
实际情况如下:
等价于:
# 首先获得Iterator对象:
iterator = iter([1, 2, 3])
# 循环:
while True:
try:
# 获得下一个值:
x = next(iterator)
print(x)
except StopIteration:
# 遇到StopIteration就退出循环
break
把一个类作为一个迭代器使用需要在类中实现两个方法 __iter__() 与 __next__() 。
如果你已经了解的面向对象编程,就知道类都有一个构造函数,Python 的构造函数为 __init__(), 它会在对象初始化的时候执行
__iter__() 方法返回一个特殊的迭代器对象, 这个迭代器对象实现了 __next__() 方法并通过 StopIteration 异常标识迭代的完成。
from itertools import islice
class Fib:
def __init__(self):
self.prev = 0
self.curr = 1
def __iter__(self):
return self
def __next__(self):
self.prev,self.curr = self.curr,self.prev+self.curr
return self.curr
f = Fib()
print(list(islice(f ,0,10)))
结果如下:
[1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
Fib既是一个可迭代对象(因为它实现了 __iter__方法),又是一个迭代器(因为实现了 __next__方法)
如何判断是可迭代对象还是迭代器?如何把可迭代对象转换为迭代器?
from collections import Iterator # 迭代器
from collections import Iterable # 可迭代对象
s = 'hello'
print(isinstance(s, Iterator)) # 判断是不是迭代器
print(isinstance(s, Iterable)) # 判断是不是可迭代对象
print(isinstance(iter(s), Iterator)) # 把可迭代对象转换为迭代器 iter(s)
博客:https://blog.csdn.net/sunchengquan/article/details/84494101
博客:https://blog.csdn.net/sumatch/article/details/99072268