zoukankan      html  css  js  c++  java
  • 面试题-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

  • 相关阅读:
    pandas Dataframe filter
    process xlsx with pandas
    data manipulate in excel with easyExcel class
    modify registry in user environment
    add number line in vim
    java import webservice
    ctypes MessageBoxA
    music 163 lyrics
    【python实例】自动贩卖机
    【python基础】sys模块(库)方法汇总
  • 原文地址:https://www.cnblogs.com/yoyoketang/p/14459595.html
Copyright © 2011-2022 走看看