• 面试题-python 什么是迭代器(Iterator)?


    前言

    python 里面有 3 大神器:迭代器,生成器,装饰器。在了解迭代器之前,需弄清楚2个概念:
    1.什么是迭代
    2.什么是可迭代对象

    迭代

    如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代(Iteration)
    在Python中,迭代是通过for ... in来完成的。

    """
    列表a中大于0的值,得到新的列表
    """
    a = [1, -2, 3, -5, 7]
    
    c = []
    for i in a:
        if i > 0:
            c.append(i)
    print(c)  # [1, 3, 7]
    

    Iterable 可迭代对象

    在python 里面 list、tuple、dict、set、str 这些基础数据类型都是可以作用于for循环的。
    可以使用 isinstance() 判断一个对象是否是 Iterable 对象:

    """
    isinstance 判断实例类型
    Iterable 可迭代对象
    """
    
    from collections import Iterable
    
    a = 12
    print(isinstance(a, Iterable))
    b = "abc"
    print(isinstance(b, Iterable))
    c = [1, 2, 3]
    print(isinstance(c, Iterable))
    d = (1, 2, 3)
    print(isinstance(d, Iterable))
    e = {1, 2, 3}
    print(isinstance(e, Iterable))
    f = {"key": 1}
    print(isinstance(f, Iterable))
    
    运行结果
    False
    True
    True
    True
    True
    True
    

    除了上面的6种基础的是可迭代的,还有一类是 生成器(generator),包括生成器和带yield的 生成器函数

    Iterator 迭代器

    可以被 next() 函数调用并不断返回下一个值的对象称为迭代器:Iterator。
    可以使用isinstance() 判断一个对象是否是 Iterator 对象:

    from collections import Iterable, Iterator
    
    a = 12
    print(isinstance(a, Iterator))
    b = "abc"
    print(isinstance(b, Iterator))
    c = [1, 2, 3]
    print(isinstance(c, Iterator))
    d = (1, 2, 3)
    print(isinstance(d, Iterator))
    e = {1, 2, 3}
    print(isinstance(e, Iterator))
    f = {"key": 1}
    print(isinstance(f, Iterator))
    结果返回
    False
    False
    False
    False
    False
    False
    

    list、dict、str虽然是可迭代对象 (Iterable),却不是 迭代器 (Iterator), 可以使用 iter() 函数,变成迭代器

    # 作者-上海悠悠 QQ交流群:717225969
    # blog地址 https://www.cnblogs.com/yoyoketang/
    
    from collections import Iterable, Iterator
    
    b = "abc"
    new_b = iter(b)
    
    print(new_b)
    print(isinstance(new_b, Iterator))
    
    c = [1, 2, 3]
    print(iter(c))
    print(isinstance(iter(c), Iterator))
    
    d = (1, 2, 3)
    print(iter(d))
    print(isinstance(iter(d), Iterator))
    
    e = {1, 2, 3}
    print(iter(e))
    print(isinstance(iter(e), Iterator))
    
    f = {"key": 1}
    print(iter(f))
    print(isinstance(iter(f), Iterator))
    

    迭代器 iter() 和 next()

    迭代器有两个基本的方法:iter() 和 next()。
    使用iter() 创建一个迭代器后,可以使用next() 输出迭代器的下一个元素

    a = [1, 2, 3, 4]
    it = iter(a)    # 创建迭代器对象
    print(next(it))   # 输出迭代器的下一个元素
    
    print(next(it))
    
    输出结果
    1
    2
    

    也可以使用 for 来遍历

    a = [1, 2, 3, 4]
    it = iter(a)    # 创建迭代器对象
    for x in it:
        print(x, end=" ")
    输出结果
    1 2 3 4 
    

    如果用next() 函数取值,一直取到没有了,那就会抛出"StopIteration" 异常

    a = [1, 2, 3, 4]
    it = iter(a)    # 创建迭代器对象
    
    print(next(it))
    print(next(it))
    print(next(it))
    print(next(it))
    print(next(it))   # StopIteration
    

    运行结果

    1
    2
    3
    4
    Traceback (most recent call last):
      File "D:/xx.py", line 9, in <module>
        print(next(it))
    StopIteration
    

    如果用next()输出全部值,可以加个try...expect

    a = [1, 2, 3, 4]
    it = iter(a)    # 创建迭代器对象
     
    while True:
        try:
            print(next(it))
        except StopIteration:
            break
    

    创建迭代器

    把一个类作为一个迭代器使用需要在类中实现两个方法 __iter__()__next__()
    __iter__() 方法返回一个特殊的迭代器对象, 这个迭代器对象实现了__next__() 方法并通过 StopIteration 异常标识迭代的完成。
    __next__() 方法(Python 2 里是 next())会返回下一个迭代器对象。
    创建一个返回数字的迭代器,初始值为 1,逐步递增 1:

    class MyNumbers:
    
        def __iter__(self):
            self.a = 1
            return self
    
        def __next__(self):
            x = self.a
            self.a += 1
            return x
    
    myclass = MyNumbers()
    myiter = iter(myclass)
    print(next(myiter))
    print(next(myiter))
    print(next(myiter))
    输出结果
    1
    2
    3
    

    StopIteration

    StopIteration 异常用于标识迭代的完成,防止出现无限循环的情况,在 __next__() 方法中我们可以设置在完成指定循环次数后触发 StopIteration 异常来结束迭代。

    class MyNumbers:
    
        def __iter__(self):
            self.a = 1
            return self
    
        def __next__(self):
            if self.a <= 3:
                x = self.a
                self.a += 1
                return x
            else:
                raise StopIteration
    
    myclass = MyNumbers()
    myiter = iter(myclass)
    print(next(myiter))
    print(next(myiter))
    print(next(myiter))
    # 第4次会抛异常
    print(next(myiter))
    

    在 3 次迭代后停止执行

    斐波那契数列

    斐波那契数列指的是这样一个数列 0, 1, 1, 2, 3, 5, 8, 13,特别指出:第0项是0,第1项是第一个1。从第三项开始,每一项都等于前两项之和
    求出小于100 的所有的斐波那契数列

    # 作者-上海悠悠 QQ交流群:717225969
    # blog地址 https://www.cnblogs.com/yoyoketang/
    
    
    class MyNumbers:
    
        def __iter__(self):
            self.n1 = 0
            self.n2 = 1
            self.count = 1
            return self
    
        def __next__(self):
            self.n1, self.n2 = self.n2, self.count
            self.count = self.n1 + self.n2
            if self.count <= 100:
                return self.count
            else:
                raise StopIteration
    
    myclass = MyNumbers()
    myiter = iter(myclass)
    while True:
        try:
            print(next(myiter), end=" ")
        except StopIteration:
            break
    
    # 也可以用 for 遍历输出 
    for i in myiter:
        print(i, end=" ")
    

    输出结果:2 3 5 8 13 21 34 55 89

  • 相关阅读:
    angularJS实现无刷新文件下载
    入门程序,hello world
    rabbitMQ概念详细介绍
    rabbitMQ安装
    truncate与delete的区别
    Java 并发编程:线程间的协作(wait/notify/sleep/yield/join)
    Java多线程编程:Callable、Future和FutureTask浅析
    定时任务 Crontab命令 详解
    使用Spring Session做分布式会话管理
    AngularJS ui-router (嵌套路由)
  • 原文地址:https://www.cnblogs.com/yoyoketang/p/14459595.html
Copyright © 2020-2023  润新知