zl程序教程

您现在的位置是:首页 >  后端

当前栏目

python中的迭代器生成器到底有啥区别,看这篇就懂了

Python迭代 区别 到底 生成器 这篇
2023-06-13 09:12:57 时间

什么是迭代器

在介绍生成器之前,我们必须了解这几个概念的区别。

迭代协议,迭代协议,可迭代对象到底是什么,它们有什么不同。

迭代协议,迭代协议,可迭代对象

什么是迭代协议:

在前一篇提到过,python中魔法函数构成了数据结构自定义的协议。我们可以基于这个协议去定义自己的方法类去达到自己的目的,Python提供了两个魔法方法,分别是__iter__和__next__。又为了支持for...in...行为,牵扯进了__getitem__,这写函数是实现迭代协议的关键。

迭代器是什么?

迭代器是访问集合内元素的一种方式, 一般用来遍历数据,迭代器和以下标的访问方式不一样, 迭代器是不能返回的, 迭代器提供了一种惰性方式数据的方式。

什么是可迭代对象?

Python中可迭代对象(Iterable)并不是指某种具体的数据类型,它是指存储了元素的一个容器对象,且容器中的元素可以通过__iter__( )方法或__getitem__( )方法访问。__iter__方法的作用是让对象可以用for … in循环遍历,getitem( )方法是让对象可以通过“实例名[index]”的方式访问实例中的元素。两个方法的目的是Python实现一个通用的外部可以访问可迭代对象内部数据的接口。

一个可迭代对象是不能独立进行迭代的,而是需要迭代器去迭代。

自定义迭代器

需要两个方法:__iter__, __next__,为了满足设计规范,我们一般将迭代器和迭代对象分开封装。代码如下:

from collections.abc import Iterator

class Company(object):

def __init__(self, employee_list):

self.employee = employee_list

def __iter__(self):

return MyIterator(self.employee)

class MyIterator(Iterator):

def __init__(self, employee_list):

self.iter_list = employee_list

self.index = 0

def __next__(self):

#真正返回迭代值的逻辑

try:

word = self.iter_list[self.index]

except IndexError:

raise StopIteration

self.index += 1

return word

if __name__ == "__main__":

company = Company(["yancy", "yancy1", "yancy2"])

my_itor = iter(company)

for item in company:

print (item)

什么是生成器

生成器函数,函数里只要有yield关键字,生成器对象, python编译字节码的时候就产生了。下面有个用生成器生成斐波那契数的例子。

def gen_fib(index):

n,a,b = 0,0,1

while n<index:

yield b

a,b = b, a+b

n += 1

for data in gen_fib(10):

介绍生成器之前我们得先了解什么是函数,已经python中得函数在内存里是怎么运行的。

python解释器会用一个叫做 PyEval_EvalFramEx(c函数)去执行函数, 首先会创建一个栈帧(stack frame),所有的栈帧都是分配在堆内存上,这就决定了栈帧可以独立于调用者存在。当一个函数又调用子函数,又会创建一个栈帧。

python一切皆对象,函数执行时会生成两个对象栈帧对象, 字节码对象。

函数执行过程如图

注意:和静态的语言函数执行过程不一样,静态语言是会创建一个栈。堆与栈的区别有:1、栈由系统自动分配,而堆是人为申请开辟;2、栈获得的空间较小,而堆获得的空间较大;3、栈由系统自动分配,速度较快,而堆一般速度比较慢;4、栈是连续的空间,而堆是不连续的空间。

生成器原理

生成器的原理是将这些上图中的栈帧又封装了一层

因为有了f_lasti,f_locals,所以生成器可以知道下次从哪里运行。这就是生成器的原理,我将它类比于一个递归函数。

新浪微博|是yancy呀

微信号|ToLiveIsToRest