您的位置:首页 > 编程语言 > Python开发

Python高级特性之Generator

2018-03-09 12:07 537 查看
第一次写博客,排版格式什么的不是很熟悉,so,看内容就好了:)
要说清楚什么是Generator(生成器),就要讲什么是Iterator(迭代器)。

Iterator(迭代器)和Iterable(可迭代对象)
什么是Iterator(迭代器)呢?Python官方解释如下:
An iterator is an object that implements next, which is expected to return the next element of the iterable object that returned it, and raise a StopIteration exception when no more elements are available.简单翻译一下:Iterator(迭代器)是一个实现了next 方法的对象,这个 next 方法执行会返回下一个Iterable(可迭代对象)的值,当没有下一个Iterable(可迭代对象)的值可以返回的时候,就抛出 StopIteration 错误。
这个时候我们可以看到,又多了一个概念Iterable(可迭代对象),没关系,我们再看一下Python官方介绍:
An iterable object is an object that implements __iter__, which is expected to return an iterator object.简单翻译一下:Iterable(可迭代对象)是一个实现了 __iter__ 方法的对象,__iter__ 方法被用来返回Iterator(迭代器)对象。
有点懵圈?举个例子,list(列表)、dict(字典)、tuple(元组)都是Iterable(可迭代对象),但他们不是Iterator(迭代器),因为他们没法实现 next 方法。
还有一个简单的判断方法,可以用于 for 循环的都是Iterable(可迭代对象),可以用于 next 的都是Iterator(迭代器),Iterable(可迭代对象)包含Iterator(迭代器)。

Generator(生成器)
Generator(生成器)实际上就是Iterator(迭代器)的一种。Python官方介绍如下:Generator functions allow you to declare a function that behaves like an iterator, i.e. it can be used in a for loop.简单翻译一下:Generator(生成器) 可用于For 循环,是一种Iterator(迭代器)。g = (x * x for x in range(10))g 即是一个简单的Generator(生成器)对象,右边为Generator Expression(生成器表达式),返回Generator(生成器)对象。def fib():
prev, curr = 0, 1
while True:
yield curr
prev, curr = curr, curr + prev注意,fib 方法返回用的不是return ,而是yield 。什么是yield 呢?当一个函数使用yield ,第一次执行从函数第一行开始,在yield 处返回,第二次执行时从返回处继续(恢复执行),当执行到yield 时再返回。return则是每次执行都从函数第一行开始执行,当执行到return 时返回。
参考stack overflow高票解析,yield 有一下特性:
yield 返回一个Generator(生成器);
带有yield 的函数被调用时,函数代码并不会马上执行,等到用for 进行迭代时再执行;
理解上面恢复执行的概念。
def AddOnePlusThree():
print("Begin.")
while True:
print("Start.")
result = 1 + 3
yield result
print("Restart.")
当执行以下代码时,a = AddOnePlusThree()
print(a)
next(a)
print('')
next(a)
print('')
next(a)返回结果如下:<generator object AddOnePlusThree at 0x03264FC0>
Begin.
Start.

Restart.
Start.

Restart.
Start.

Process finished with exit code 0请结合恢复执行的概念进行理解。
for循环用来调用yield 返回的生成器的值。b= AddOnePlusThree()

for item in b:
print('')
print(item)返回结果如下:Begin.
Start.

4
Restart.
Start.

4
Restart.
Start.

4
...
...请结合恢复执行的概念进行理解。上面的例子可能没什么实际意义,下面实现一个Fibonacci 生成器。def fibon(n):
a = b = 1
for i in range(n):
yield a
a, b = b, a + b

for x in fibon(10):
print(x)返回结果如下:1
1
2
3
5
8
13
21
34
55

Process finished with exit code 0实际上,n 如果很大时,Fibonacci 生成器的作用才能体现出来,因为生成器是当运行时产生值,而且只能迭代一次,并不像list 那样将所有值全部扔到内存中。
关于Generator(生成器)暂时先讲到这里吧。
以上。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: