Python生成器

Date:2018/06/4       Cat:开发者手册       Word:共1558字       Tags:      

文章目录 「隐藏」
  1. 什么是生成器(generator)?
  2. 生成器(generator)函数
  3. 生成器(generator)表达式

什么是生成器(generator)?

在Python中提供了一种名为generator的对象,他是通过next函数去中断执行并且generator对象具有Iterable对象,也就是说可以用于for循环,generator最大的作用是按需生成值,这个是什么意思呢?当我们需要一组元素很多的列表的时候会占用很大的内存,比如你需要生成一组从0-100000的列表,那么这个列表的长度将有10万,这是多么大的列表?如果比这个数值更大呢?那么很大一部分内存都将用来保存这个列表。

list(range(100000))

类似于上面这样的情况,我们可以用generator对象来按需生成数值来供我们处理,你可以把generator对象理解为一种状态机,里面保存着每次执行后的状态而并不是一次性的生成所有的值,我们就相当于导演,generator对象就像一个演员,我们叫他cut的时候,他就会停止,这样的好处就是一次性只返回一个或少量的值,不会一次性大量生成所有的值而导致内存的紧缺。

生成器(generator)函数

生成器函数和普通函数很相似,为什么?因为你看见一个函数内部只要出现yield标识符,那么这个函数肯定就是generator对象函数,比如下面的代码:

#普通函数
def ad(a,b):
    return a + b

#generator函数
def ad(a,b):
    yield a + b
    return None

但是他们的执行过程却不一样,普通函数调用过后就马上执行内部的代码并返回,而generator对象函数却是保存了内部的状态,等待你需要的时候再去执行,而执行我们通过next函数去调用并且在内部执行的时候遇见了下一个yield标识符就会停止执行并返回yield标识符后面的值。

#普通函数
def ad(a,b):
    return a + b

#generator函数
def ad(a,b):
    yield a + b
    return None

#普通函数执行
ad(1,5)
#6

b = ad(1,5)
#此时保存了状态

next(b)
#6 通过next函数调用generator函数执行

生成器(generator)表达式

生成器表达式和列表表达式很像,但是有一点不同的是列表表达式由[]组成,而生成器表达式由()组成,就像下面的代码一样:

l = [x * x for x in range(5)]
#列表表达式

g = (x * x for x in range(5))
#生成器表达式

generator对象是需要通过next函数调用执行,并且返回的值是按循环生成的每个元素,我们每次用next执行我们的generator对象后,generator对象会保存执行后的状态,直到没有元素或者遇见return语句后抛出一个StopIteration错误来表示已经执行完毕,下面的代码是通过手动执行generator对象和通过for自动执行。

g = (x for x in range(5))
#生成器表达式

next(g)
#0

next(g)
#1

next(g)
#2

next(g)
#3

next(g)
#4

next(g)
#
Traceback (most recent call last):

  File "<ipython-input-18-e734f8aca5ac>", line 1, in <module>
    next(g)

StopIteration

从上面的代码看出来当我们调用内部的代码已经执行完了后,我们再次执行就会扔出StopIteration类型的错误,当然我们也可以直接给next设置默认返回值,当执行完内部的所有代码后就会返回这个默认值

g = (x for x in range(5))
#生成器表达式

next(g,'ok')
#0

next(g,'ok')
#1

next(g,'ok')
#2

next(g,'ok')
#3

next(g,'ok')
#4

next(g,'ok')
#返回 'ok'

《Python生成器》留言数:0

发表留言