• 迭代器和生成器


    迭代

    通过for遍历访问一个列表或者容器里的所有元素,这个遍历我们就可以称之为迭代。

    可以被for循环的都是可迭代的类型,可迭代类型内部一定有__iter__方法。

    迭代器

    每个可迭代对象内部都有__iter__方法,当可迭代对象执行了__iter__方法就成了一个迭代器

    print([1, 2, 3].__iter__())
    
    # 结果 <list_iterator object at 0x7f21fbd581d0

     我们利用dir 来查看下迭代器 和可迭代对象之间有什么不同的方法

    list1 = [1, 2, 3, 4, 5]
    iter1 = list1.__iter__()
    print(set(dir(iter1)) - set(dir(list1)))
    
    # 结果 {'__length_hint__', '__setstate__', '__next__'}

    可以看到 迭代器 比 可迭代对象多了三个方法

    # 查看迭代器内共有多少元素
    print(iter1.__length_hint__())
    
    # 指定迭代器从第几个元素开始迭代
    iter1.__setstate__(2)
    for i in iter1:
        print(i)
    
    # 从迭代器中取下一个值
    print(iter1.__next__())
    print(iter1.__next__())
    print(iter1.__next__())

     注意:next方法会如果一直取值,当迭代器没有值可以取的时候,会抛出一个异常StopIteration,异常处理如下

    while True:
        try:
            print(iter1.__next__())
        except StopIteration:
            break

    range()方法是什么类型

    print("__iter__" in dir(range(1, 10)))  # True
    print("__next__" in dir(range(1, 10)))  # False

    可以看出range内有iter方法,但是没有next方法,由此,range方法得到的是一个可迭代对象,而不是一个迭代器

    from collections import Iterator
    
    print(isinstance(range(100000000), Iterator))  # 验证range执行之后得到的结果不是一个迭代器

    生成器

    迭代器的功能就是节省内存,为了实现这一功能,有的时候我们需要自己定义一个迭代器,我们自己定义的这个具有迭代器功能的就是生成器

    实现:和函数定义一样,不同的是使用yeild语句返回结果而不是return,yield一次返回一个结果,返回之后挂起函数状态,下一次执行从该处继续执行,

      可以说一个包含了yield关键子的函数就是生成器,调用生成器函数会返回一个生成器对象

    用生成器写一个range()

    def my_range(start, stop, step):
        n = start
        while n < stop:
            yield n
            n += step
    
    
    for i in my_range(1, 100, 3):
        print(i)
  • 相关阅读:
    1、第一个JSP
    eclipse汉化
    学习计划与目标
    还在用系统自带的?那你那就OUT了!
    zabbix api调用
    C#中使用泛型对照使用通用基础类型效率减少近一倍
    Android应用架构之MVP---&gt;天气实例
    JavaFX打包到Android上
    2015 Multi-University Training Contest 3
    用Android Studio 执行ndk 程序
  • 原文地址:https://www.cnblogs.com/ligiao/p/11241861.html
Copyright © 2020-2023  润新知