(python)迭代器

一、迭代器

迭代是一个重复的过程,并且每次重复都是基于上一次的结果而来。
在了解迭代器到之前先了解一个概念,即什么是可迭代的对象。
可迭代的对象就是在python中,但凡内置有__iter__方法的对象,都是可迭代对象。
如str字符串,list列表,tuple元组,dict字典,set集合,file文件,这些都是可迭代对象。
迭代器对象是要求支持迭代器协议的对象,在python中,支持迭代器协议就是实现对象的__inter()和__next__()方法。其中__iter__()方法返回迭代器对象本身,__next__()方法返回容器的下一个元素,如果没有下一个元素时引发StopIteration异常。

for循环原理分析:

for item in ...:
    #循环体
    ...

    1、for 循环称之为迭代器循环,in后跟的必须是可迭代的对象.
    2、for循环会执行in后对象的__iter__方法,拿到迭代器对象.
    3、然后调用迭代器对象的__next__方法,拿到一个返回值赋值给item,执行一次循环体.
    4、周而复始,直到取值完毕,for循环会检测到StopIteration异常自动结束循环.

自定义迭代器

了解迭代器之后,我们可以写一个自己定义的迭代器


class MyRange:
    def __init__(self,n):
        self.n=n
        self.o=0

    def __iter__(self):
        return self

    def __next__(self):
        if self.o<self.n:
            result=self.o
            self.o+=1
            return result
        else:
            raise StopIteration

myrange=MyRange(5)

上面的例子中实现了一个MyRange的类型,这个类中我分别实现了__iter__()方法来返回对象本身作为一个迭代器对象,实现__next__()方法来获取迭代器中的下一个元素,当没有可访问的下一个元素时,就引发StopIteration导常。

迭代器对象和可迭代对象

可迭代的对象:str,list,tuple,dict,set,file
 1、获取可迭代对象的方式:
 无须获取,python内置str,list,tuple,dict,set,file都是可迭代对象
 2、特点:
     内置有__iter__方法的都叫可迭代的对象,执行该方法会拿到一个迭代器对象
迭代器对象:文件(file)对象本身就是迭代器对象
 1、获取迭代器对象的方式:
    执行可迭代对象的__iter__方法,拿到的返回值就是迭代器对象
 2、特点:
    内置有__next__方法,执行该方法会拿到迭代器对象中的一个值
    内置有__iter__方法,执行该方法会拿到迭代器本身

迭代器的优缺点分析
优点:
    1、提供了一种可不依赖于索引的取值方式。
    2、 迭代器更加节省内存。
缺点:
    1、取值麻烦,只能一个一个往后取。
    2、是一次性的取值过程,无法用len()获取数据长度。

在上面的自定义迭代器例子中,myrange这个对象即是可迭代对象,又是迭代器对象。它会出现没有办法多次迭代的问题。

print([i for i in myrange])
print([i for i in myrange])

#结果
#[0, 1, 2, 3, 4]
#[]

为了解决上面的问题,我们可以分别定义可迭代类型和迭代器类型;其中可迭代类型对象的__iter__方法可以获得一个迭代器类型的对象。

class MyRange:
    def __init__(self,n):
        self.o=0
        self.n=n

    def __iter__(self):
        return MyRangeIterator(self.n)

class MyRangeIterator:
    def __init__(self,n):
        self.n=n
        self.o=0

    def __iter__(self):
        return self

    def __next__(self):
        if self.o<self.n:
            result=self.o
            self.o+=1
            return result
        else:
            raise StopIteration
myrange=MyRange(5)
print([i for i in myrange])
print([i for i in myrange])

#运行结果
#[0, 1, 2, 3, 4]
#[0, 1, 2, 3, 4]

在python中list类型也是以这样子的方式去实现的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值