• python编程系列---可迭代对象,迭代器和生成器详解


    一、三者在代码上的特征

    1.有__iter__方法的对象就是可迭代类(对象)
    2.有__iter__方法,__next()方法的对象就是迭代器
    3.生成器 == 函数+yield       

    生成器属于迭代器, 迭代器是特殊的可迭代对象

    二、各自的执行过程

    1.可迭代对象执行过程

       1.先调用iter()函数:  iter(iterable) -> iterator : 函数传入一个可迭代对象(iterable),返回迭代器(iterator);
      内部是通过可迭代对象(iterable)的__iter__ ()取得迭代器(iterator)

      2.再调用next()函数:  next(iterator)->Return the next item from the iterator : 函数传入一个迭代器(iterator),返回迭代器指向的下一个值;

      内部是通过迭代器(iterator)的__next__ ()取得下一个值(iitem)

    代码如下:

     1 # 定义一个可迭代对象,如列表
     2 list1 = [1, 2, 3, 4, ]
     3 
     4 # 通过iter()生成一个迭代器
     5 list_iterator = iter(list1)
     6 
     7 # 通过next()取得迭代器指向的下一个元素,默认从第一个开始
     8 print("第1个迭代出的元素:",next(list_iterator))
     9 print("第2个迭代出的元素:",next(list_iterator))
    10 print("第3个迭代出的元素:",next(list_iterator))
    11 print("第4个迭代出的元素:",next(list_iterator))
    12 
    13 
    14 
    15 结果如下:
    16 第1个迭代出的元素: 1
    17 第2个迭代出的元素: 2
    18 第3个迭代出的元素: 3
    19 第4个迭代出的元素: 4
    20 
    21 进程已结束,退出代码 0

    补充:

            列表元祖等是可迭代对象,但不是可迭代器,虽然可以调用内部__iter__方法,返回的是一个迭代器,但不是自己的本身(本身就不是生成器),所以不能直接所以不能直接调用next()返回迭代器指向的下一个值,必须先调用iter()方法

    2.yield实现生成器的执行过程

    1. 假如函数中有yield,则不再是函数,而是生成器
    2. yield 会产生一个断点,暂停函数 ,挂起函数, 且保存当前状态
    3. 假如yield后面紧接着一个数据,就会把数据返回,
    作为next()函数或者for ...in...迭代出的下一个值
    4. 可以通过next()唤醒生成器,让生成器从断点处继续执行

    代码如下:

    def fibo(n):
        """使用yield实现生成器求斐波那契数列"""
        count = 0  # 记录当前迭代的位置,初始值为0
        num1, num2 = 0, 1  # 初始化数列的前两位值 0,1
        while count < n:
            yield num1
            num1, num2 = num2, num1 + num2
            count += 1  # 自加一,迭代器指针指向下一个位置
    
    
    # 创建生成器,生成器默认是沉睡的,假如是第一次唤醒生成器(函数),则从生成器(函数)的起始位置开始运行
    gen = fibo(10)
    
    # 使用next()迭代
    print("返回的值:", next(gen))
    print("返回的值:", next(gen))
    print("返回的值:", next(gen))
    print("返回的值:", next(gen))
    print("返回的值:", next(gen))
    print("返回的值:", next(gen))
    print("返回的值:", next(gen))
    print("返回的值:", next(gen))
    print("返回的值:", next(gen))
    print("返回的值:", next(gen))
    
    
    结果如下:
    返回的值: 0
    返回的值: 1
    返回的值: 1
    返回的值: 2
    返回的值: 3
    返回的值: 5
    返回的值: 8
    返回的值: 13
    返回的值: 21
    返回的值: 34
    
    
    进程已结束,退出代码 1

    三、总结三者拿到迭代出的数据的方法如下:

      生成器 :  可使用next()/send()    拿到数据
       迭代器:   可使用next() 拿到数据
       可迭代对象(只是可迭代对象):    可使用iter() +next() 拿到数据

    如果你和我有共同爱好,我们可以加个好友一起交流!

  • 相关阅读:
    LeetCode Ugly Number
    LeetCode Missing Number
    拓扑排序
    不相交集的求并算法(按集合大小求并+按高度求并)
    数据结构排序总结
    基数排序
    java 发展简史
    java 白皮书的关键术语
    包+类导入+静态导入+类放入包中+包作用域
    关于二叉堆(优先队列)的其他操作及其应用
  • 原文地址:https://www.cnblogs.com/ywk-1994/p/9457506.html
Copyright © 2020-2023  润新知