python:到底什么是迭代器,它和for循环有什么关系?

python:浅析迭代器

1、什么是迭代器

​ 迭代器是访问集合元素的一种方式,迭代器是一个可以记住遍历位置(索引)的对象。迭代器从集合的第一个元素开始访问,直到所有的元素都被访问完结束

2、什么是可迭代

​ 基本上我们知道的可迭代对象有:list、str、tuple、dict、set这些数据类型都可以使用for……in循环遍历(从容器呢内部依次获取数据),这种过程除了叫遍历以外,它还叫迭代。

3、如何检测可迭代对象

# 使用 collections包下的Iterable模块
from collections import Iterable
# 然后使用一个方法isinstance
print(isinstance(object,Iterable))
# 当返回True时说明是可迭代对象,返回False则不是,该方法输出控制台会抛出一个警告,并不是异常
#即:
.py:1: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated since Python 3.3, and in 3.9 it will stop working
  from collections import Iterable

# 例如:
mylist = [1,2,3,4,5]
print(isinstance(mylist,Iterable))

4、如何检测迭代器

# 使用collections包下的Iterator
from collections inport Iterator
# 同样使用isinstance方法
print(isinstance(object,Iterator))
# 当返回True时说明是迭代器,返回False则不是,该方法输出控制台会抛出一个警告,并不是异常

#示例:
print(isinstance(MyList,Iterator))

5、自定义可迭代对象

​ (1)如果想要一个对象成为可迭代对象,也就是说使用Class类实例出来的对象可以直接使用for循环遍历,那么这个对象中必须实现一个方法_iter_

​ (2)如果想让一个可迭代对象成为迭代器,则将必须继续使用__next__方法,那么也就是说成为迭代器的条件为实 现 __iter__和__next__方法,二者缺一不可。

​ (3) __iter__方法是迭代对象的核心方法,它每次返回一个迭代器即自身,那么也就是说每次真正迭代的核心控制者是是迭代器

​ (4)而__next__方法的作用就是返回每次迭代的最终数据,也是迭代器每次进行迭代工作的最终结果

​ (5)在__next__方法中引发一个StopIteration 异常,是迭代结束的标志,也就是终止迭代

class MyList(object):
    def __init__(self):
        # 初始化一个列表
        self.panel = list()
        # 记录迭代器每次迭代的位置
        self.current_index = 0

     # 向列表属性panel中添加数据
    def add(self,element):
        self.panel.append(element)
	
    # 要想成为可迭代对象,则必须使用__iter__方法,该方法必须返回一个迭代器。也就是说每次for遍历的时候会直接调用该方法
    def __iter__(self):
        # 返回迭代器每次迭代的最终数据
        return self
	
    # 要想成为迭代器,必须先成为可迭代对象,然后使用__next方法成为迭代器。该方法必须返回一个迭代出来的结果。也就是说每次for循环遍历的时候会间接调用__next__方法
    def __next__(self):
        # 当迭代器的位置小于列表的长度
        if self.current_index < len(self.panel):
            # 那么就使用索引的方式取出列表中的值
            result = self.panel[self.current_index]
            # 取完之后,迭代器位置就要+1
            self.current_index += 1
            # 最终返回某个索引位置的列表元素
            return result
        # 因为索引不可能等于或大于列表的长度,但是迭代器不知道
        else:
            # 当大于等于的时候引发一个异常,该异常为停止接迭代
            raise StopIteration

# 实例化可迭代对象
mylist = MyList()
# 通过add方法向列表中添加元素
mylist.add(1)
mylist.add(2)
mylist.add(3)

# 最后使用for循环将触发可迭代对象中的__iter__方法,促使调用__next__方法,最终通过for循环不断迭代,达到我们想要的结果
for item in mylist:
    print(item)

6、可迭代的本质

​ 可迭代对象在进行迭代的时候,每迭代一次(即在for……in中循环一次)都会返回可迭代对象中的下一条数据,一直向后读取,直到迭代完最后一个数据的结果。那么在这个过程中,就应该有一个特殊的成员去记录每次访问到的第几条数据,这个成员每次迭代都可以记录好数据,以便下次迭代,我们把这个能帮助我们进行数据迭代的成员称为 迭代器

7、for循环的本质

​ for循环的本质就是先通过__iter__这个方法获取可迭代对象的迭代器,然后对获取的迭代器进行不断调用__next_方法,来获取下一个值,并将其赋值给临时变量i就是in前边的那个临时变量,当遇到StopIteration异常对象则终止循环。

8、使用迭代器算某一位之前的斐波那契数列

# 要想成为迭代器,首先必须是一个对象,所有class跑不了
class MyList(object):
    
     # 使用__init__方法定义属性
    # 并且实例对象之前要传进来一个参数,表示要查找的位数
    def __init__(self, n):
        # self.x: 用来记录迭代器每次迭代的位置
        # 因为斐波那契数列是有规律的,所有我们用a和b来模拟前两个数字,来算出后一个数字
        # self.a 为前两个数字
        # self.b 为前一个数字
        self.index, self.a, self.b, self.num = 0, 0, 1, n
        
    # 要想成为迭代器首先得先使用iter方法成为可迭代对象
    def __iter__(self):
        # 该方法要返回一个迭代器对象,因为自己就是迭代器,所有返回自身实例self
        return self
    
    # 要想成为迭代器,必须实现next方法,并且返回每次迭代出来的数据
    def __next__(self):
        # 在这里其其实self.num就是用户传过来的要查找的位数,那么也就是长度
        # 那么迭代器迭代的位置索引肯定不能大于长度
        if self.index < self.num:
            # 当要第一位数字的时候,我把b给a,因为b是1,然后b来算前两位的和,那么b=a+b=1,那么第二位就算出来了
            # 当要第三位的时候,此时b=a+b=1+1=2,然后再给a
            # 那么也就是说b起到的作用就是记录上一次的数字,并且算下一位的数字
            # 而a起到的作用是记录前两次的数字和返回给用户
            self.a, self.b = self.b, self.a + self.b
            # 迭代器迭代位置每次+1
            self.index+=1
            return self.a
        else:
            # 当大于或等于的时候就停止迭代
            raise StopIteration

# 最后调用
if __name__ == '__main__':
    while True:
        try:
            num = int(input("请输入要算的位数:"))
        except:
            print("请输入正确的数字格式:")
        else:
            mylist = MyList(num)
            for item in mylist:
                print(item)
            break

        
        
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

御弟謌謌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值