Python高级特性之Generator

本文介绍了Python中的生成器、迭代器及可迭代对象的概念,并通过实例详细讲解了它们之间的区别与联系,同时探讨了生成器在实际应用中的优势。

第一次写博客,排版格式什么的不是很熟悉,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 有一下特性:

  1. yield 返回一个Generator(生成器);
  2. 带有yield 的函数被调用时,函数代码并不会马上执行,等到用for 进行迭代时再执行;
  3. 理解上面恢复执行的概念。
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(生成器)暂时先讲到这里吧。

以上。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值