Python 可迭代对象与迭代器

什么是迭代呢?平时我们经常说到迭代,比如软件迭代,指的是软件版本更新,但如果你仔细想想,它都是在有一定的版本之后 做的更新,即在原有的基础上做的更新。而python中的迭代也类似。

在python中,一切皆对象,那么可迭代对象即是内容实现了__iter__方法的对象。

这里就牵涉到怎么查看对象有哪些方法:我们可以使用内置的dir()方法来查看对象有哪些方法。
 

In [3]: name = 'andy'
In [4]: '__iter__' in dir(name)
Out[4]: True

所以,可迭代对象就是可以重复取值的对象, 但凡内部含有__iter__方法的对象,都是可迭代对象。

可迭代对象的优点是:可以直观的查看里面的数据,但缺点是,占用内存,且不能迭代取值。

那我们为什么可以通过for循环取值呢?因为 for循环在底层做了一个小小的转化,就是先将可迭代对象转化成迭代器,然后在进行取值。

迭代器:

实现了无参数的__next__方法,返回序列中的下一个元素,如果没有元素了,那么抛出StopIteration异常.python中的迭代器还实现了__iter__方法,因此迭代器也可以迭代。  

迭代器迭代取值只能前进,不能后退。

那么要怎么判断是不是迭代器呢? 根据上面的描述,可以知道,迭代器既实现了__iter__方法,又实现了___next__方法,所以对此进行判断就行了。

In [5]: n = []

In [6]: '__iter__' in dir(n) and '__next__' in dir(n)
Out[6]: False

可以看到列表不是迭代器,那么常见的 list dict, tuple, string,set, range, file 哪个是迭代器呢,只有文件句柄是,其它的全不是。

怎么将这些可迭代对象转化成迭代器呢?

In [9]: n=n.__iter__()

In [10]: '__iter__' in dir(n) and '__next__' in dir(n)
Out[10]: True

迭代器取值:

In [14]: n = [1,2,4]

In [15]: obj = n.__iter__()

In [16]: obj.__next__()
Out[16]: 1

In [17]: obj.__next__()
Out[17]: 2

while循环模拟for循环:

for循环的循环对象一定要是可迭代对象,但是这不意味着可迭代对象就可以取值,因为for循环的内部机制是:将可迭代对象转换成迭代器,然后利用next进行取值,最后利用异常处理处理StopIteration抛出的异常

l1 = [1, 2, 3, 4, 5, 6]
# 1 将可迭代对象转化成迭代器
obj = iter(l1)
# 2,利用while循环,next进行取值
while 1:
    # 3,利用异常处理终止循环
    try:
        print(next(obj))
    except StopIteration:
        break

迭代器的优点:
     节省内存: 迭代器在内存中相当于只占一个数据的空间:因为每次取值都上一条数据会在内存释放,加载当前的此条数据。
     惰性机制:next一次,取一个值,绝不过多取值。​
迭代器的缺点:            
     不能直观的查看里面的数据。          
      取值时不走回头路,只能一直向下取值。

 

对比:

 可迭代对象:

    是一个私有的方法比较多,操作灵活(比如列表,字典的增删改查,字符串的常用操作方法等),比较直观,但是占用内存,而且不能直接通过循环迭代取值的这么一个数据集。

    应用:当你侧重于对于数据可以灵活处理,并且内存空间足够,将数据集设置为可迭代对象是明确的选择。

迭代器:

    是一个非常节省内存,可以记录取值位置,可以直接通过循环+next方法取值,但是不直观,操作方法比较单一的数据集。

    应用:当你的数据量过大,大到足以撑爆你的内存或者你以节省内存为首选因素时,将数据集设置为迭代器是一个不错的选择

上一篇:Python f-string

下一篇:Python 反射