您现在的位置是:首页 > 学无止境 > 其他网站首页其他 Python 迭代器

Python 迭代器

  • 莫愁
  • 其他
  • 2019-08-07
简介迭代器和生成器,是Python语言的一大特定。这两个概念我们可能还不理解,但是我们前面的学习中已经有所接触,比如用for...in遍历一个列表、字典、元组,就是使用了迭代器。
字数 2272

迭代器和生成器,是Python语言的一大特定。这两个概念我们可能还不理解,但是我们前面的学习中已经有所接触,比如用for...in遍历一个列表、字典、元组,就是使用了迭代器。

迭代器

 

可迭代对象(iterable)

这个概念我们前面已经学过,这里提到是为了更好理解迭代器。从字面上看,可迭代对象和迭代器有很大关系,迭代器作用在可迭代对象上面,逐一返回可迭代对象的元素。也就是说,可以通过for循环遍历的对象就可以称为可迭代对象。Python内置的数据类型中,是可迭代对象的有:str, list, tuple, dict, set。这些数据结构都是用来存放其它对象的,也称为“容器”。

 

迭代器(iterator)

for循环遍历列表(我们以列表为例,元组和字典等类似)的背后就是迭代器起的作用,Python有两个内置函数iter()next()可以把这些可迭代对象显示转换为迭代器并进行遍历。先看看下面的代码:

In [1]: ll = [1,2,3]

In [2]: for n in ll:
    ...:     print(n)
    ...:
1
2
3

In [3]: itr = iter(ll)

In [4]: itr?
Type:        list_iterator
String form: <list_iterator object at 0x7fc0483c9828>
Docstring:   <no docstring>

In [5]: next(itr)
Out[5]: 1

In [6]: next(itr)
Out[6]: 2

In [7]: next(itr)
Out[7]: 3

In [8]: next(itr)
----------------------------------------------------
StopIteration         Traceback (most recent call last)
<ipython-input-8-6693cc261707> in <module>
----> 1 next(itr)

StopIteration: 

通过iter()内置函数,我们就可以得到list对象的迭代器(这实际上是调用的ll.__iter__()),得到的是一个list_iterator对象;然后我们就可以用内置函数next()遍历这个迭代器(实际上是调用的ll.__next__())。每次调用next()都能得到ll的一个元素,其是按顺序依次返回ll的元素,也就是说,迭代器机制了当前元素的位置。当元素遍历完毕时,就会引发StopIteration的异常。从此,我们最初得到的迭代器itr就不可以再迭代,因为它已经迭代到末尾。

通过上面的例子,我们可以看出一些迭代器的端倪。其实,迭代器就是定义了__iter__()方法来返回一个带有__next__()方法的对象的对象。按照这个定义,我们不用内置函数而是用__iter__()__next__()来迭代一下列表对象:

In [9]: ll
Out[9]: [1, 2, 3]

In [10]: itr = ll.__iter__()

In [11]: itr
Out[11]: <list_iterator at 0x7fc048dcdcc0>

In [12]: itr.__next__()
Out[12]: 1

In [13]: itr.__next__()
Out[13]: 2

In [14]: itr.__next__()
Out[14]: 3

In [15]: itr.__next__()
----------------------------------------------
StopIteration       Traceback (most recent call last)
<ipython-input-15-fc6e27a9fb4c> in <module>
----> 1 itr.__next__()

StopIteration: 

可以看出,这实现了和内置函数iter()next()同样的效果。实际上,内置函数iter()就是调用了迭代器的__iter__()方法,而next()就是调用了迭代器的__next__()方法。

明白了迭代器的内部机制(称为“迭代器协议”),我们就可以在自定义类中添加迭代器行为了:

In [21]: class LessThan:
     ...:     '''遍历比给定整数小的正整数的迭代器'''
     ...:     def __init__(self, n):
     ...:         self.n = n
     ...:
     ...:     def __iter__(self):
     ...:         return self
     ...:
     ...:     def __next__(self):
     ...:       
     ...:         if self.n == 0:
     ...:             raise StopIteration
     ...:         self.n -= 1
     ...:         return self.n 

In [23]: lt = LessThan(5)

In [24]: lt
Out[24]: <__main__.LessThan at 0x7fc048d3acc0>

In [25]: iter(lt)
Out[25]: <__main__.LessThan at 0x7fc048d3acc0>

In [26]: for n in lt:
     ...:     print(n, end=' ')
     ...:
4 3 2 1 0 

lt是我们自定义类LessThan的一个对象,通过内置函数iter()可以得到它的迭代器,它们两个完全一样,都是<__main__.LessThan at 0x7fc048d3acc0>,因为内置函数和iter()其实调用的就是lt.__iter__()方法,而这个方法返回的就是它本身(带有__next__()方法)。

 

总结

(1)可迭代对象:
可以通过for循环遍历的对象都是可迭代对象。本质上,定义了__iter__()方法或__getitem__()方法的对象就是可迭代对象。

(2)迭代器:
定义了__next__()方法的对象就是一个迭代器。迭代器迭代到末尾就会引起Stopiteration异常。

(2)内置函数iter()next()
iter()作用于可迭代对象得到迭代器;next()对迭代器进行遍历。

(3)自定义类
自定义类中定义__iter__()方法和__next__()方法,实现迭代器;


转载: 感谢您对莫愁个人博客网站平台的认可,非常欢迎各位朋友分享到个人站长或者朋友圈,但转载请说明文章出处“来源莫愁个人博客 https://www.mochoublog.com/study/308.html”。

上一篇:Python类的继承

下一篇:Python 生成器

文章评论

    • 评论
    人参与,条评论

技术在线

服务时间

周一至周日 12:00-22:00

关闭下雪
关闭背景特效