Iterator-Generator

Python3 迭代器与生成器

一、关系架构

Python数据结构中常用的概念:
容器(container)、可迭代对象(iterable)、迭代器(itertor)、生成器(generator)的关系及概念如下
image

二、详细描述

1.容器 container

由关系图可知,容器由集合、元组、字典等产生,是一种可以把多个元素组织在一起的数据结构 通常把这些元素存储在内存中(但也有特例,比如迭代器和生成器对象) 常见的容器对象:

  • list, deque, ….

  • set, frozensets, ….

  • dict, defaultdict, OrderedDict, Counter, ….

  • tuple, namedtuple, …

  • str

可以询问某元素是否在容器中:

2.可迭代对象

很多容器是可迭代对象,所有可以返回一个迭代器的对象都是一个可迭代对象

比如一个打开的file ,socket

例如:

​ 这里x是一个可迭代对象,可迭代对象和容器一样是一种通俗的叫法,并不是指某种具体的数据类型,list是可迭代对象,dict是可迭代对象,set也是可迭代对象。yz是两个独立的迭代器,迭代器内部持有一个状态,该状态用于记录当前迭代所在的位置,以方便下次迭代的时候获取正确的元素。迭代器有一种具体的迭代器类型,比如list_iteratorset_iterator。可迭代对象实现了__iter__方法,该方法返回一个迭代器对象。

实际执行情况:

image

3.迭代器

迭代器(itertor)是可以记住遍历位置的对象,是访问集合元素的一种方式,从第一个元素开始直到遍历结束 任何实现了__iter__ __next__ 方法的都是迭代器前者返回迭代器自身,后者返回下一个值,若无其他元素则抛出StopIteration异常

基本方法:

:black_flag: iter():传入一个序列对象,建立其对应的迭代器对象

:black_flag: next():访问下一个元素

实例:

生成无限序列:

由无限序列截取有限序列:

以斐波那契数列定义迭代器:

Fib既是一个可迭代对象(因为它实现了__iter__方法),又是一个迭代器(因为实现了__next__方法)。实例变量prevcurr用户维护迭代器内部的状态。每次调用next()方法的时候做两件事:

  1. 为下一次调用next()方法修改状态

  2. 为当前这次调用生成返回结果

迭代器就像一个懒加载的工厂,等到有人需要的时候才给它生成值返回,没调用的时候就处于休眠状态等待下一次调用。

4.生成器

​ 生成器算得上是Python语言中最吸引人的特性之一,生成器其实是一种特殊的迭代器,不过这种迭代器更加优雅。它不需要再像上面的类一样写__iter__()__next__()方法了,只需要一个yiled关键字。

生成器一定是迭代器(反之不成立),因此任何生成器也是以一种懒加载的模式生成值。用生成器来实现斐波那契数列的例子是:

fib就是一个普通的python函数,它特殊的地方在于函数体中没有return关键字,函数的返回值是一个生成器对象。当执行f=fib()返回的是一个生成器对象,此时函数体中的代码并不会执行,只有显示或隐示地调用next的时候才会真正执行里面的代码。

生成器在Python中是一个非常强大的编程结构,可以用更少地中间变量写流式代码,此外,相比其它容器对象它更能节省内存和CPU,当然它可以用更少的代码来实现相似的功能。现在就可以动手重构你的代码了,但凡看到类似:

5.生成器表达式

生成器表达式是以列表推导式的方式建立生成器的版本,但是返回的是一个生成器对象

Last updated

Was this helpful?