迭代器

面试:迭代器,生成器
实际开发:协程 gevent

可迭代对象:列表/字典/元组/字符串/集合/文件对象 ...

类似实际生活中看书的时候,看到哪一页就在那一页中放一个书签,
主要是为了快速翻到那一页,迭代就是类似于翻书的过程.每次都有一个工具将我们读到哪一页
这个位置记录下来.

迭代器的作用:帮助 我们记录迭代过程的工具.称之为迭代器.里面记录的是位置信息.
在每次遍历之后,会自动的向下移动一个位置.并记住这个位置.
用户直接找迭代器要即可,
记录遍历的位置信息.
记录迭代的位置信息.

iter(可迭代对象) 把第一个元素放进来,并返回迭代器(就是自己)
next(iter(可迭代对象))

if __name__ == '__main__':
    data = [1, 2, 3, 4, 5]
    # 遍历   --> 迭代  这个过程就是迭代
    # for i in data:
    #     print(i)

#  模拟for循环的过程
    # 取出对象中的迭代器
    # 1.取出可迭代对象的首个元素,放入迭代器中,并返回迭代器
    i = iter(data)
    # 2.不断 通过迭代器取出下一个元素的值,直到 迭代完成,抛出StopIteration: 停止迭代的异常
    # print(next(iter(data)))
    print(next(i))
    print(next(i))
    print(next(i))
    print(next(i))
    print(next(i))
    # print(next(i))
    # 如果迭代完成,则抛出异常  StopIteration

迭代器实现for循环:

if __name__ == '__main__':
    data = [1, 2, 3, 4, 5]
    # for i in data:
    #     print(i)

    # 模拟for 遍历的  过程
    # 1.取出迭代器
    it = iter(data)  # 每次都是取出第一个元素
    while True:
        # 通过迭代器取出下一个元素的值<返回值>
        try:
            # it = iter(data)  # 每次都是取出第一个元素,不能放在这里,否则就是死循环.
            i = next(it)  # 迭代器的返回值赋给i
        # 如果迭代完成,则抛出StopIteration异常
        except Exception as e:
            print(e)
            break
        else:
            print(i)

自定义实现迭代器:

class FibIter:
    def __init__(self, n):
        self.n = n
        self.num1 = 1
        self.num2 = 1
        self.count = 0

    def __iter__(self):
        """iter(对象):取出对象的迭代器 作为本对象  通过__iter()__返回一个迭代器"""
        return self  # 类是迭代器,所以创建的对象就是可迭代对象

    def __next__(self):
        """值 = next(迭代器)  作为本对象 通过__next__()反复返回下一个元素的值"""
        if self.count < self.n:
            ret = self.num1
            # 打包/拆包
            self.num1, self.num2 = self.num2, self.num1 + self.num2
            self.count += 1
            return ret
        else:
            raise StopIteration


# n提前不准备数据,只是需要使用的时候才会去计算所需要的那一个,延迟计算.  Python实现的延迟计算(也成为懒惰计算)
if __name__ == '__main__':
    # 1 1 2 3 5 8 13
    # 创建一个实例对象
    f = FibIter(10)

    # 如果能够遍历

    # 法1:
    # for i in f:
    #     print(i)

    # 法2:
    it = iter(f)  # 每次都是取出第一个元素  实际上是去调用__iter__()方法 自动调用魔法方法.
    while True:
        # 通过迭代器取出下一个元素的值<返回值>
        try:
            # it = iter(data)  # 每次都是取出第一个元素,不能放在这里,否则就是死循环.
            i = next(it)  # 迭代器的返回值赋给i  自动调用__next__() 魔法方法.
        # 如果迭代完成,则抛出StopIteration异常
        except Exception as e:
            print(e)
            break
        else:
            print(i)


"""
总结:
1.> 迭代器: 记录迭代的位置信息的对象
    操作:
        迭代器= iter(可迭代对象)  --> 可迭代对象.__iter__()
        下一个元素的值= next(迭代器)  --> 迭代器.__next__() 
        
    判断:
        isinstance(对象,类型)  判断对象是否是xxx类型  返回值是True或者False
        isinstance(对象,迭代器类型)
        isinstance(对象,Iterator)  # 首先要导入 from collections import Iterator
        
2.> 实现迭代器
        魔法方法: Python 预先自定义功能的方法.
        __iter__()方法  提供迭代器<返回self  毛遂自荐>
        __next__()方法  提供下一个元素


可迭代对象:
    可以被迭代的对象
    判断:for循环遍历(偶尔使用还行)
    from collections import Iterable
    isinstance(obj,Iterable)  # 判断一个对象是否是可迭代类型
    
    结论:迭代器一定是可迭代对象
    可迭代对象 不一定是迭代器  <只需要实现__iter__()方法提供迭代器>

面试:    
迭代器需要实现那些方法?  
    __iter__()  __next__()
    
可迭代对象需要实现那些方法?   __next__() 可以有,也可以没有
    __iter__()  -> 可迭代对象的标识    可迭代对象的范围更大<包含了迭代器>
    
    
迭代器和可迭代对象的区别  
    迭代器一定是可迭代对象/可迭代对象 不一定是迭代器
    
如何判断对象是否是可迭代对象/迭代器
    isinstance(obj,Iterable) ---> 可迭代对象
    isinstance(obj,Iterator) ---> 迭代器
    
示例:
from collections import Iterator
d = [1,2,3,4]
isinstance(d,Iterator)
Out[15]: False

d1 = iter(d)
isinstance(d1,Iterator)
Out[15]: True


from collections import Iterable
isinstance(d,Iterable)
Out[17]: True


"""
原文地址:https://www.cnblogs.com/huaibin/p/12098094.html