深入浅出迭代器&生成器

    xiaoxiao2022-07-14  154

    深入浅出迭代器&生成器

    前言

    真正的开发中,迭代器使用不多,生成器更常用。生成器是特殊的迭代器,为了掌握生成器的工作原理,必须先了解迭代器原理。本文章案例使用的是python语言

    知识点

    for循环原理

    可迭代对象

    迭代器原理

    生成器的定义、原理和优点

    生成器函数(主要了解yield的作用)

    迭代

    定义:每一次对过程的重复称为一次“迭代”,而每一次迭代得到的结果会作为下一次迭代的初始值。(循环地使用自己定义自己)

    这有两道相关的经典面试题:

    可以被for的条件?------ 对象具有__iter__方法,即能返回迭代器对象

    不使用for循环,获取字典所有记录.

    for循环语句的原理:可分为以下三个步骤

    步骤1:获取迭代器对象(具有__iter__方法的对象) iterator = (1,2,3,4).__iter__() while True: try: # 步骤2:循环获取下一个元素,既是使用迭代器对象的__next__方法 item = iterator.__next__() print(item) #步骤3:处理异常 except StopIteration: break

    可迭代对象iterable

    定义:具有__iter__函数的对象,可以返回迭代器对象。

    语法

    1. 创建: class 可迭代对象名称: def __iter__(self): return 迭代器 2. 使用: for 变量名 in 可迭代对象: 语句

    原理:

    迭代器 = 可迭代对象.__iter__() while True: try: print(迭代器.__next__()) except StopIteration: break

    迭代器对象iterator

    定义:可以被__next__函数调用并返回下一个值的对象。

    语法

    class 迭代器类名: def __init__(self, 聚合对象): self.聚合对象= 聚合对象 def __next__(self): if 没有元素: raise StopIteration return 聚合对象元素

    说明:聚合对象通常是容器对象。

    作用:使用者只需通过一种方式,便可简洁明了的获取聚合对象中各个元素,而又无需了解其内部结构。

    练习:将自定义类对象迭代(for 自定义类的对象)

    目的:更深入地了解迭代器工作原理 """ 练习:参照下列代码,定义类MyRange实现函数range一样的功能 for i in MyRange(5): print(i) """ class RangeIteration: def __init__(self, target): self.end = target self.start = 0 def __next__(self): if self.start > self.end-1: raise StopIteration result = self.start self.start += 1 return result class MyRange: def __init__(self, end): self.end = end def __iter__(self): return RangeIteration(self.end) for i in MyRange(5): print(i)

    生成器generator

    定义:能够动态(循环一次,计算一次,返回一次)提供数据的可迭代对象。

    将可迭代对象一个个地提供出去

    作用:

    优点:在循环过程中,按照某种算法推算数据,不必创建容器存储完整的结果,从而节省内存空间。数据量越大,优势越明显。

    以上作用也称之为延迟操作或惰性操作,通俗的讲就是在需要的时候才计算结果,而不是一次构建出所有结果。

    缺点:不能通过索引/切片操作生成器对象

    第一次遍历生成器对象时,返回可迭代对象,再次执行时不会返回可迭代对象

    # 延迟/惰性操作 # 优点:不会将所有结果计算出来,存储在内存中. # 缺点:通过索引/切片灵活的访问结果. # 解决:将延迟操作 转为 立即操作 result = list(result) print(result[0].name) for item in result: print(item.name) # 调用生成器函数,创建一个生成器对象 result = find03(list01) # 使用一次 for item in result: print(item.name) # 再使用一次(没有执行find03函数.) for item in result: print(item.name)

    生成器内置类

    return 和 yield的区别:return返回一个数据,并退出方法;yield返回数据,暂时离开方法(不会退出方法)。

    生成器=迭代器对象+可迭代对象(同时具有iter和next方法)

    class MyGenerator: """ 等同与整数生成器range 备注:本类是生成器的"源码",只需要看,不需要写. 生成器:可迭代对象 + 迭代器对象 """ def __init__(self, stop_value): self.__stop_value = stop_value self.__start_value = 0 def __iter__(self): return self def __next__(self): if self.__start_value >= self.__stop_value: raise StopIteration() result = self.__start_value self.__start_value += 1 return result

    生成器函数

    定义:含有yield语句的函数,返回值为生成器对象。

    语法

    1. 创建: def 函数名(): yield 数据 2. 调用:生成器调用须使用for语句,因为for会调用__next__ for 变量名 in 函数名(): 语句

    说明:

    调用生成器函数将返回一个生成器对象,不执行函数体。

    yield翻译为”产生”或”生成”

    执行过程:

    调用生成器函数会自动创建迭代器对象。

    调用迭代器对象的_next_()方法时才执行生成器函数。

    每次执行到yield语句时返回数据,暂时离开。

    待下次调用_next_()方法时继续从离开处继续执行。

    原理:生成迭代器对象的大致规则如下

    将yield关键字以前的代码放在__next__方法中。

    将yield关键字后面的数据作为__next__方法的返回值。

    内置生成器

    枚举函数enumerate

    语法:for 变量 in enumerate(可迭代对象): 语句

    作用:遍历可迭代对象时,可以将索引与元素组合为一个元组。

    zip

    语法: for item in zip(可迭代对象1, 可迭代对象2….): 语句作用:将多个可迭代对象中对应的元素组合成一个个元组,生成的元组个数由最小的可迭代对象决定。

    生成器表达式

    定义:用推导式形式创建生成器对象。

    语法:变量 = ( 表达式 for 变量 in 可迭代对象 [if 真值表达式] )

    最新回复(0)