文章目录
- 前言
- 一、迭代器介绍及作用
- 1.可迭代对象
- 2. 迭代器
- 二、常用函数和迭代器
- 1.常用函数
- 2.迭代器
- 三、总结
- 结束语
- 💂 个人主页:风间琉璃
- 🤟 版权: 本文由【风间琉璃】原创、在CSDN首发、需要转载请联系博主
- 💬 如果文章对你有
帮助
、欢迎关注
、点赞
、收藏(一键三连)
和订阅专栏
哦
前言
Python有三大器:迭代器
、生成器
、装饰器
。这里给大家先介绍迭代器相关的知识。
一、迭代器介绍及作用
1.可迭代对象
在介绍迭代器之前介绍一下迭代和可迭代对象的概念:
迭代
:通常从一个对象中依次取出数据,这个过程叫做遍历,也称为**迭代(**重复执行某一段代码块,并将每一次迭代得到的结果作为下一次迭代的初始值)。
可迭代对象
:是指该对象可以被用于for循环,例如:集合,列表,元组,字典,字符串,迭代器等。直接作用于for循环的对象统称为可迭代对象(Iterable)
那么在代码层面如何定义一个可迭代对象呢?
在python中如果一个对象实现了__iter__方法
,则该对象可以称之为可迭代对象
。例如,可以查看list,set等其内部均实现了__iter__方法,实现方式和对象的初始化方法一样。
class MyIterable:
def __init__(self):
pass
def __iter__(self):
return self
如果一个对象未实现__iter__方法
,对其使用for则会抛出TypeError: ‘xxx’ object is not iterable。
MyIterable实现了__iter__方法,则MyIterable就是一个可迭代对象。可以通过如下方式判断一个对象是不是可迭代对象?
# 导入collections.abc模块中的Iterable对象
import collections.abc
class MyIterable:
def __init__(self):
pass
def __iter__(self):
return self
obj = MyIterable()
# 判断str是否可迭代
a = isinstance(obj, collections.abc.Iterable)
# 打印迭代结果
print(a)
2. 迭代器
迭代器
:对可迭代对象进行迭代的方式或容器,并且需要记录当前迭代进行到的位置。
Python迭代器可以被定义为:
⋆
\star
⋆ 在python中如果一个对象同时实现了__iter__
和__next__
(获取下一个值)方法
⋆
\star
⋆ 可以通过内置函数next(iterator)
或实例对象的__next__()方法
,来获取当前迭代的值
⋆
\star
⋆ 迭代器一定是可迭代对象,可迭代对象不一定是迭代器。
⋆
\star
⋆ 如果可迭代对象遍历完后继续调用next(),则会抛出:StopIteration异常
。
注意第三点,一个对象要同时实现__iter__
和__next__
才 可以称为迭代器,只有实现__iter__方法的称为可迭代对象。可通过如下方式判断一个对象是不是迭代器?
# 导入collections.abc模块中的Iterable对象
import collections.abc
class MyIterable:
def __init__(self):
pass
def __iter__(self):
return self
obj = MyIterable()
# 判断str是否可迭代
a = isinstance(obj, collections.abc.Iterable) # True
b = isinstance(obj, collections.abc.Iterator) # False
# 打印迭代结果
print(a)
print(b)
从这里可以看到obj是可迭代对象,但不是迭代器。常见数据类型Iterable和Iterator分类:
你可能会问,为什么list、dict、str等数据类型不是Iterator?
这是因为Python的Iterator对象
表示的是一个数据流
,Iterator对象可以被next()函数
调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误
。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。
下面是一个简单的Python迭代器示例:
# 导入collections.abc模块中的Iterable对象
import collections.abc
class MyIterable:
def __init__(self, mylist):
self.mylist = mylist # 列表
self.index = 0 # 索引
def __iter__(self):
return self
def __next__(self):
if self.index < len(self.mylist):
value = self.mylist[self.index]
self.index += 1
return value
else:
raise StopIteration
mylist = [1, 2, 3, 4, 5]
iterableobj = MyIterable(mylist) # 迭代器(可迭代对象)
# a = isinstance(iterableobj, collections.abc.Iterable) # True
# b = isinstance(iterableobj, collections.abc.Iterator) # False
在这个示例中,我们创建了一个称为"MyIterable"的类,它包含了一个列表和一个索引值。该类还实现了__iter__()和__next__()方法。因此iterableobj是一个迭代器(可迭代对象)。
__iter__()方法
返回该对象本身
,因此可以直接对该对象使用for…in…语句进行迭代。
__next__()方法
则根据当前索引值来获取列表中的下一个元素
,如果已经到达列表末尾,则抛出StopIteration异常
。因此有两种方法打印输出。
(1)使用for循环打印输出
for item in iterableobj:
print(item)
(2)使用next函数
while True:
try:
# 获得下一个值:
x = next(iterableobj)
print(x)
except StopIteration:
# 遇到StopIteration就退出循环
break
注意不要两种方式一起用,一起使用的话,只会打印输出一次,可能是由于底层都是调用的迭代器吧,迭代器会记录当前迭代的位置,使用其中一种方式后,迭代器计数器已经到末尾了,当第二次使用的时,自然啥也不会输出。
二、常用函数和迭代器
1.常用函数
2.迭代器
三、总结
优点:迭代器对象表示的是一个数据流
,可以在需要时才去调用next来获取一个值;因而本身在内存中始终只保留一个值,对于内存占用小可以存放无限数据流。由于其他容器需要一次将所有元素都存放进内存,如:列表、集合、字典…等
缺点:无法获取存放的元素长度,除非取完计数。同时取值不灵活,只能向后取值,next()永远返回的是下一个值;无法取出指定值(如字典的key,或列表的下标),而且迭代器对象的生命周期是一次性的,元素被迭代完则生命周期结束。
Python 的迭代器提供稳定和灵活的代码。迭代器和可迭代对象的区别:
⋆
\star
⋆ Iterable
是一个可以迭代的对象
。它在传递给iter()
方法时生成一个迭代器
。
⋆
\star
⋆ Iterator
是一个对象,用于使用 __next__()
方法对可迭代对象进行迭代
。迭代器有 __next__() 方法,它返回对象的下一项。
请注意,每个迭代器也是一个可迭代的,但不是每个可迭代的都是一个迭代器。
例如,列表是可迭代的,但列表不是迭代器。可以使用函数 iter() 从可迭代对象创建迭代器。
为了实现这一点,对象的类需要一个方法 __iter__
,它返回一个迭代器,或者一个具有从 0 开始的顺序索引的 __getitem__ 方法。但其本质也是实现了 __iter__ 方法。
结束语
感谢阅读吾之文章,今已至此次旅程之终站 🛬。
吾望斯文献能供尔以宝贵之信息与知识也 🎉。
学习者之途,若藏于天际之星辰🍥,吾等皆当努力熠熠生辉,持续前行。
然而,如若斯文献有益于尔,何不以三连为礼?点赞、留言、收藏 - 此等皆以证尔对作者之支持与鼓励也 💞。