美文网首页
python 可迭代对象 迭代器 生成器 概念、场景、判断方法

python 可迭代对象 迭代器 生成器 概念、场景、判断方法

作者: 牛奶大泡芙 | 来源:发表于2020-07-13 17:41 被阅读0次

    关于迭代器生成器和可迭代对象比较容易混淆,虽然在实际代码中可能清楚地知道自己要写哪一种
    下面会介绍
    (一)可迭代对象、迭代器、生成器常用的场景
    (二)可迭代对象、迭代器、生成器概念和方法
    (三)如何判断变量是可迭代对象、迭代器还是生成器
    ***************************************** 一 ***********************************************
    理解概念可以结合常用的使用场景,这或许就是概念定义的初衷
    一般我们看见的一种用法是
    比如:

    list = [1,2,3]  
    it = iter(list)
    print(next(it))
    

    在这里list就是一个可迭代对象,具有“iter”方法
    it变成了迭代器,具有“next”方法,“next”方法可以依次单向取出it中的元素
    这个场景算是很常见的了,记住这个场景就不难理解“可迭代对象”和“迭代器”
    关于生成器,比较经典的一种是“菲波那切数列”

    def fib(num):
        a,b,counter = 0,1,0
        while True:
            if counter > num:
                return
            yield a
            a,b = b, a+b
            counter += 1
    f = fib(10)
    print(next(f))
    

    fib函数的特点就是用yield关键字来标识新元素的位置。可以发现fib函数返回的f又可以调用“next”方法了,以依次单向读取元素,也就是迭代器了,生成器生成了一个迭代器(在不使用“iter”方法的情况下)
    ***************************************** 二 ***********************************************
    下面介绍三个概念:
    1、 可迭代对象
    可以直接作用于for循环的对象
    只要定义了iter()就是可迭代对象
    例子1:
    dict,list,string

    2、 迭代器
    是遍历元素集合的一种方法,可以记住上次读取元素的位置,并通过next方法继续读取下一个元素
    是for循环实际上操作的对象
    把一个类作为迭代器使用,需要实现iter,next两个
    迭代器只能向前不能后退,不具有撤销性
    两个基本方法:iter(), next()
    例子1:
    Iter(dict), iter(list), iter(string)可以直接for循环操作

    例子2:

    class MuNumbers:
        def __iter__(self):
            self.a = 1
            return self
        def __next__(self):
            if self.a < 20:
                x = self.a
                self.a += 1
                return x
            else:
                raise StopIteration
    # 实例化
    m = MyNumbers()
    m_iter = iter(m)
    print(next(m_iter))
    

    3、 生成器
    一个返回迭代器的函数,只能用于迭代操作
    作用之一是节省内存,它可以在循环中计算,一边生成数据一边不占内存,因为每个数据使用的是一个变量
    例子1:

    G = (i+a for I in list1 for a in list2)
    

    调用方法:next(G)
    例子2:
    如下的斐波那契生成器函数

    比较常见的一个生成器函数是斐波那契,调用的方法是多样的,参考??代码

    def fib(num):
        a,b,counter = 0,1,0
        while True:
            if counter > num:
                return
            yield a
            a,b = b, a+b
            counter += 1
    
    f = fib(10)
    
    print(next(f))
    print(next(f))
    print(next(f))
    print(next(f))
    print('*******')
    print(f.__next__())
    print(f.__next__())
    print('*******')
    print([i for i in f])
    

    运行结果是这样的,可以看见next和next函数的调用效果相同,可以使生成器函数内部的数据向前移动,导致了最终遍历的时候遍历不到,其实for循环的实际操作也是按照相同的方法向下迭代的

    0
    1
    1
    2
    *******
    3
    5
    *******
    [8, 13, 21, 34, 55]
    

    ***************************************** 三 ***********************************************
    用collections判断list的类型,运行效果如下:

    list类型判断.png
    可以看出,list是可迭代对象而不是迭代器,拥有iter()方法,没有next()方法,并且在调用了iter()方法之后就变成了迭代器。

    实例化的MyNumbers具有iter方法和next方法,既是可迭代对象也是迭代器,测试结果如下:


    MyNumbers类型判断.png

    而且m与m_iter指向同一个对象

    判断inspect判断生成器


    inspect检测生成器.png

    相关文章

      网友评论

          本文标题:python 可迭代对象 迭代器 生成器 概念、场景、判断方法

          本文链接:https://www.haomeiwen.com/subject/pmkzcktx.html