我们前面章节讲到迭代的概念,迭代是指通过 for 循环遍历集合中每一个成员的过程,Python 的 for 语句可以遍历任何可迭代的对象,在 Python 中,list,tuple,str,set,dict等类型的对象都是可以迭代的。
其实只有迭代器可以迭代,但是可迭代对象不一定是迭代器,比如 list,tuple,str,set,dict 都是不是迭代器,
那为什这些可迭代对象可以迭代呢,是因为 for...in
语句在第一次遍历可迭代对象时,把该对象转换成了迭代器,然后再遍历。
迭代器是一种可以被遍历的对象,并且能作用于 Python 内置的 next 函数,迭代器对象从集合的第一个元素开始访问, 直到所有的元素被访问完结束,迭代器只能往后遍历不能回溯,迭代器必须实现两个基本的函数,__iter__ 函数和 __next__ 函数(我们在面向对象章节详解如何自己写个迭代器类)。
我们可以用 collections 模块的 Iterator 来判断对象是不是迭代器 。
from collections.abc import Iterator mystr = "hello" mylist = [1, 2, 3] mytuple = (1, 2, 3) myset = set([1, 2, 3]) mydict = {"a": 1, "b": 2, "c": 3} print(isinstance(mystr, Iterator)) # False print(isinstance(mylist, Iterator)) # False print(isinstance(mytuple, Iterator)) # False print(isinstance(myset, Iterator)) # False print(isinstance(mydict, Iterator)) # False
我们可以用 Iter 函数把一个可迭代对象作为参数,创建一个迭代器。
from collections.abc import Iterator it_mystr = iter("hello") it_mylist = iter([1, 2, 3]) it_mytuple = iter((1, 2, 3)) it_myset = iter(set([1, 2, 3])) it_mydict = iter({"a": 1, "b": 2, "c": 3}) print(isinstance(it_mystr, Iterator)) # True print(isinstance(it_mylist, Iterator)) # True print(isinstance(it_mytuple, Iterator)) # True print(isinstance(it_myset, Iterator)) # True print(isinstance(it_mydict, Iterator)) # True
生成器是迭代器。
from collections.abc import Iterator def ge_func(): yield 1 myge = (item for item in range(1)) print(isinstance(ge_func(), Iterator)) # True print(isinstance(myge, Iterator)) # True
Python 的 for 循环本质上就是在遍历对象时, 会先调用 iter 函数把这些对象转为迭代器,然后遍历,遍历就是通过不断调用迭代器的 __next__ 函数实现的。
mylist = [1, 2, 3] for item in mylist: # 解释器第一次看到 for...in 语句时,会先调用 iter 函数用 mylist 生成一个迭代器 print(item) # Python 解释器把上面 for ... in 语句转为下面代码 it_mylist = iter(mylist) # 第一次 for...in 时先利用可迭代对象 mylist 生成一个迭代器 item = it_mylist.__next__() # 第一次 for...in 时 print(item) item = it_mylist.__next__() # 第二次 for...in 时 print(item) item = it_mylist.__next__() # 第三次 for...in 时 print(item)
for 循环遍历对象时,会首先调用 iter 函数把对象变为迭代器,如果遍历的对象是不可迭代的,则在 iter 函数转换时抛出异常。
data = 5 for item in data: print(item) # Python 解释器首先把上面 for ... in 语句转为下面代码,因为 data 是不可迭代对象,所以在转化成迭代器时报异常 data = iter(data) # TypeError: 'int' object is not iterable
Python 内置的 int 类型,float类型,bool 类型,NoneType 类型都不是可迭代的对象,更不是迭代器。
Python 内置的 str 类型,list 类型,tuple 类型,dict 类型,set 类型都是可迭代的对象,但不是迭代器。
可迭代对象(str,list,tuple,dict,set)都可以通过 iter 函数转换为迭代器。
一个对象同时有 __iter__ 函数和 __next__ 函数是迭代器的充分必要条件。也就是说迭代器必须有 __iter__ 函数和 __next__ 函数,有 __iter__ 函数和 __next__ 函数的对象都是迭代器(我们在面向对象学习对象)。
生成器一定是迭代器,也就说生成器含有 __iter__ 函数和 __next__ 函数。
可迭代对象,生成器,迭代器区别。
for...in 的本质。
著名公司(某东)笔试题:写出 for...in 的每一步是如何使用 __next__ 函数遍历的。
def ge_func(): yield 1 yield 2 yield 3 for item in ge_func(): print(item)
非常感谢,我弄懂了Python的迭代器的优势了.感谢!