《老鸟python 系列》视频上线了,全网稀缺资源,涵盖python人工智能教程,爬虫教程,web教程,数据分析教程以及界面库和服务器教程,以及各个方向的主流实用项目,手把手带你从零开始进阶高手之路!点击 链接 查看详情




迭代器

阅读:227568454    分享到

我们前面章节讲到迭代的概念,迭代是指通过 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)

如果以上内容对您有帮助,请老板用微信扫一下赞赏码,赞赏后加微信号 birdpython 领取免费视频。


登录后评论

user_image
伊利杀白
2020年4月28日 07:18 回复

非常感谢,我弄懂了Python的迭代器的优势了.感谢!


user_image
Guaidaodl
2019年12月20日 21:13 回复

一直不知道迭代器是什么,现在终于清晰了


user_image
Laruence
2019年10月19日 06:05 回复

别的主流语言没有生成器的概念???c#不算主流么 我 out 了


user_image
hzlzh
2019年9月23日 08:26 回复

这回给你赞了


user_image
麦兆辉
2018年12月3日 05:06 回复

写的很好