• 三、生成器/迭代器


    思考:

    一、迭代器/可迭代对象

     1.可迭代对象(费内存)

    老版本python:range比较费内存(需要多少数据,全部存在list中,在数据量比较大的情况下非常耗内存)

    range实现过程:

    from typing import Iterable
    
    def range_test(stop):
        start = 0
        result = []
        while start < stop:
            result.append(start)
            start += 1
        return result
    
    
    if __name__ == '__main__':
        print(isinstance(range_test(10),Iterable))  # 判断返回结果是不是可迭代,True
        print(range_test(10))                     # output:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

     2.可迭代对象(省内存)

    from typing import Iterable
    
    # Next含有__next__()方法,每次变量+1,一次只占用一个数的内存
    class Next(object):
        """Next class"""
    
        def __init__(self, stop, start=-1):
            self.start = start
            self.stop = stop
    
        def __next__(self):
            if self.start >= self.stop - 1:
                raise StopIteration
            self.start += 1
            return self.start
    # 含有__iter__()方法,return调用Next
    class MyRange:
    
        def __init__(self, stop):
            self.stop = stop
    
        def __iter__(self):
            return Next(self.stop)

     使用调式模式,单步执行,可看到程序执行Next,每执行一次,生成一个数据。不耗内存

     for是迭代(自动执行__iter__,__next__),while是循环(手动指定函数)

    if __name__ == '__main__':
        print(Next(10).__next__())  # 0
        for item in MyRange(10):  # for循环自动执行__iter__,__next__方法
            print(item)
        # while循环
        num = MyRange(10).__iter__()
        i = 0
        while i < 10:
            print(num.__next__())  # 0,1,2,3,4,5,6,7,8,9
            i += 1

    3.可迭代对象定义

    可以被for迭代的对象都是可迭代对象

    对象有__iter__方法的,都是可迭代对象(如果没有__iter__方法,他不可以被for迭代),__iter__要求返回值必须是一个迭代器(严格来说,返回值必须有__next__方法)

    常见的可迭代对象;list、tuple、string、dict

    判断某个每个对象是不是可迭代对象:

    1. 可通过dir()查看所有属性中是否有__iter__方法

    2. 也可以通过hasattr(list,'__iter__'),查看list是否有__iter__方法。返回True则说明有该方法

    判断MyRange(10)是否是可迭代对象:

    print(isinstance(MyRange(10),Iterable)   返回True,则MyRange(10)是可迭代对象,因为有__iter__方法

    判断Next(10)是否是可迭代对象:

    print(isinstance(Next(10),Iterable)   返回False,则Next(10)不是可迭代对象,因为没有__iter__方法

    4.迭代器定义

    迭代器必须__iter_ __next__  属性

    核心:通过 __next__方法记住迭代的位置,有没有迭代完毕

    迭代器是特殊的可迭代对象,

    可以被for迭代,for迭代迭代器时,会自动执行__next__方法

    迭代器比较省内存,一次只给一个数。

    没有迭代器,则用不了for,只能用while

    判断Next(10)是否是迭代器

    print(isinstance(Next(10),Iterator)    # Fasle  因为虽然有__next__方法,但是缺少__iter__方法

    注意:__iter__必须返回一个迭代器(严格来说,返回值必须有__next__方法)

    二、生成器

    因为迭代器手工实现比较麻烦

    所以python提供了生成器对象,生成器对象的目的就是获得迭代器对象(非常高效)

    def fun():
        print("在yield1前面")
        yield 1
        print("在yield1后面,yield2前面")
        yield 2
    
    
    if __name__ == '__main__':
        # 验证是否是生成器
        print(fun())   # <generator object fun at 0x104d00150> 结果是一个生成器对象,但是没有运行函数
        print(hasattr(fun(),"__iter__"))  # True
        print(hasattr(fun(),"__next__"))  # True
    
        # 运行生成器,必须要调用__next__
        print(fun().__next__())  # 1 / 在yield1前面
        
        # 运行出全部结果,for自动调用__next__
        for i in fun():
            print(i)

    注意:

    • 当python解释器看到函数中有yield的时候,不会立即去调用这个函数,而是先创建一个生成器对象。而这个生成器对象会记住函数的状态

    • 在for循环中,运行到第一个yield时,就暂时退出了(类似return,但区别是return是永久跳出不会再回去了)。再次运行时(__next__记住位置),会从yield1后面开始运行

    • 当执行next(生成器对象)时,会执行生成器对象的yield.

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

    生成器是可迭代对象

    如果创建生成器对象(通过yield)

    yield:关键字

    记住函数执行的状态

    当执行next(g)时,会执行g中的yield

    yield和return的区别:

    return:跳出函数,不回来了

    yield:暂时跳出,还会回来

    生成器的使用场景:

     

    生成器为什么省内存:因为有__next__

    生成器是为了快速获得含有__iter__  __next__的方法

    场景一:我需要99999999999个数字,一下子把1——9999999999999个数字放到list中

    场景二:我需要99999999999个数字,需要1生成1,需要2生成2~~~~~需要999999999999生成999999999999

    场景二是next思想(生成器、迭代器)

    转载仅供参考:http://testingpai.com/article/1605148018144 

  • 相关阅读:
    C#/.NET CTS和CLS:公共类型系统和公共语言规范
    MongoDB分布式集群架构(3种模式)
    Elastic Search 入门
    转:计算机视觉部分会议/期刊名称缩写
    神经网络模型的参数量和FLOPs的计算,torchstat,thop,循环神经网络RNN
    latex自己调配颜色
    latex图像和表格手动设置位置(清除自动寻找位置)
    转:图像泊松融合
    latex调整表格行高、列宽和表格整体的左右宽度
    转:目标检测评价标准mAP
  • 原文地址:https://www.cnblogs.com/zhangjx2457/p/14038475.html
Copyright © 2020-2023  润新知