一.递归和迭代

递归:自己执行自己,就是一直执行自己这个函数,每次执行,问题都变得更加简单

迭代:“代”,更新换代。每次循环的结果都是依赖上一次的结果而产生的。

二.迭代器协议

迭代器协议:对象必须提供一个next方法,执行这个方法只有两个结果,进入下一层or引起一个异常从而终止迭代。(只能往后不能往前)

迭代器对象:实现了可迭代协议的对象。如列表

 

迭代器协议是一种约定:例如,for循环遵循了迭代器协议,从而将列表,元组中的每一个元素进行了迭代。

三.python中强大的for循环机制

for循环的本质:利用迭代器协议,循环所有对象!

 

正本清源:!!!!!

  for循环后面跟着的可以是列表啊,字符串啊,字典啊这些东西,这就意味着,这些数据类型都是可迭代对象。

  但是,[123,345,567]这个东西写出来有next()功能吗?

  显然没有!

  根本原因:字符串,列表,元组,字典,这些都不是可迭代对象!!

  那为什么for循环可以对这些数据类型进行操作呢?

    答案来了:for循环在针对这些个比比赖赖们操作时,自动调用了他们的_iter_方法,使他们成为了可迭代对象。

  

x="hello"
iter_test=x.__iter__()
print(iter_test)         #输出结果为<str_iterator object at 0x000001E9D227FC40>。是一个迭代器类似的吧
print(iter_test.__next__())         #输出h
print(iter_test.__next__())         #输出e
print(iter_test.__next__())         #...
print(iter_test.__next__())
print(iter_test.__next__())
print(iter_test.__next__())   #会报错StopIteration,因为已经遍历了一遍了

  

总结:for循环的两个功能(1)帮你把列表之类的东西变成可迭代对象

              (2)帮你识别出来异常stopiteration

∴for循环只是通过迭代器协议的方式进行取值,打印,和通过索引打印没有半毛钱的关系

l=[1,2,3]
#之前通过索引取值
print(l[0])
#现在先将l变成可迭代对象之后在进行取值
iter_1=l.__iter__()
print(iter_1.__next__())

  

四.为什么需要for循环?

 我们通过while循环,只通过索引的方式就可以遍历元素,那我为他妈的啥,还需要for循环(迭代器协议)呢?

  答案:因为字符串你可以通过索引找到值,列表也可以,但是集合呢?字典呢?你丫找不到了把。所以,引入了for循环。

dic={"yxz":1,"ymz":2}
iter_1=dic.__iter__()
print(iter_1.__next__())       #输出结果为yxz

  👆👆👆就是字典通过调用——iter——,变成可迭代对象,再用next输出,输出的就是key值

for循环干了什么事,用while来表示(理解即可)

l=[1,2,3,4,5]
diedai_1=l.__iter__()
while True:
    try:
        print(diedai_1.__next__())
    except StopIteration:
        print("迭代结束")
        break

  ⭐for循环就是基于迭代器提供了一个统一的可以遍历所有对象的方法,即在遍历之前,先调用对象的__iter__方法将其转换称一个迭代器,然后使用迭代器协议实现循环访问,这样所有的对象就可以通过for循环进行遍历了。

 

五.迭代器的补充

next方法就是调用迭代器的值,是系统内置的方法。类似于数据类型内置的__next__函数

l=[1,2,3,4,5]
iter_l=l.__iter__()
print(iter_l.__next__())
print(next(iter_l))           #这两行代码是一样的结果,只不过第三行是数据类型自带的功能,第四行是python系统内置的函数