前言
大家周末好,今天给大家带来的是Python当中生成器和迭代器的使用。
我当初第一次学到迭代器和生成器的时候,并没有太在意,只是觉得这是一种新的获取数据的方法。对于获取数据的方法而言,我们会一种就足够了。但是在我后来Python的使用以及TensorFlow等学习使用当中,我发现很多地方都用到了迭代器和生成器,或者是直接使用,或者是借鉴了思路。今天就让我们仔细来看看,它们到底是怎么回事。
迭代器
我们先从迭代器开始入手,迭代器并不是Python独有的概念,在C++和Java当中都有iterator的概念,两者的使用也都差不多。迭代器主要解决了一个问题,在一个复杂场景下,获取数据怎么尽可能简便。
我们来假设一个场景,假设我们从某个数据源获取了一批数据。然后我们需要调用前一万条生成一个结果,得到结果之后,我们要将剩下的数据交给另一个调用方去处理。这个过程看起来非常平常,但是隐藏了两个问题,第一个问题是如果我们能保证第一次处理的时候,每次都是使用一万条还好说,如果我们使用的条数是一个动态的值呢?显然,我们需要一个变量来记录我们究竟用了多少条数据,和这批数据的状态。其次,如果这个数据量很大会存在一个数据传输的问题。我们每次都要将一大批数据传来传去,显然会消耗很多资源。
还有一个场景是如果我们开发的是一个比较复杂的数据结构,比如一棵多叉树,下游想要遍历它的时候,必须要了解它的实现原理才行。这显然也不太友好。
迭代器的出现正是针对以上这些问题,它的含义也很简单,有点像是我们遍历链表的时候用到的cur的指针。永远指向当前的位置,永远知道下一个位置在哪里。
容器迭代器
我们先从简单的元素迭代器开始了解它的用途,我们都知道Pytho来2源gaodaima#com搞(代@码&网n当中经典的几个容器:list
, tuple
和dict
。它们都是一个可迭代对象,我们可以直接使用关键字iter获取一个对应的迭代器。
我们来看一个例子:
arr = [1, 3, 4, 5, 9] it = iter(arr) print(next(it)) print(next(it))
这是一个非常经典的例子,我们首先定义了一个数组,然后通过iter
关键字获取了一个读取它的迭代器。有了迭代器之后我们可以通过next
关键字获取迭代器当中的下一个元素,我们一共调用了两次next
,第一次输出的结果是1,第二次的结果是3。和我们刚才说的一样,我们每一次调用,它会自动往后移动一格,获取后面一位的数据。
这里有一点需要注意,因为我们创建的数组当中一共只有5个元素,如果我们调用it的次数超过5次,那么会引发超界,Python的解释器会抛出StopIterat****ion的error。
除了使用next,我们也可以使用for循环来迭代它:
for i in it: print(i)
这种用法就和我们用for循环遍历元素是一样的。
自定义迭代器
官方的迭代器的用法就这么多,这也不是它的主要用法,它最主要的用法是我们自己创建迭代器。和之前介绍Python自定义排序的时候的思路一样,我们为类添加上__iter__
方法和__next__
方法即可。
其中__iter__
方法用来初始化并返回迭代器,关于它的解释比较复杂。在Python当中迭代有两个概念一个是iterable
,一个是iterator
。协议规定iteratble的__iter__方法会返回一个iterator。而iterator本身也是一个iterable对象,自然也需要实现__iter__方法。