如何更好的理解python生成器?

本文详细介绍了Python生成器的概念、生成器函数和表达式,以及它们如何节省内存并提高代码可读性。通过实例展示了生成器在生成无限序列和处理大文件时的应用,强调了理解和掌握生成器对于提升Python编程技能的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

在Python这门语言中,生成器毫无疑问是最有用的特性之一。与此同时,也是使用的最不广泛的Python特性之一。究其原因,主要是因为,在其他主流语言里面没有生成器的概念。正是由于生成器是一个“新”的东西,所以,它一方面没有引起广大工程师的重视,另一方面,也增加了工程师的学习成本,最终导致大家错过了Python中如此有用的一个特性。

一、何为生成器?

顾名思义,迭代器就是用于迭代操作(for 循环)的对象,它像列表一样可以迭代获取其中的每一个元素,任何实现了 next 方法(python2 是 next)的对象都可以称为迭代器。

Python有两种不同的方式提供生成器:

  • 生成器函数:常规函数定义,但是,使用yield语句而不是return语句返回结果。yield语句一次返回一个结果,在每个结果中间,挂起函数的状态,以便下次重它离开的地方继续执行
  • 生成器表达式: 类似于列表推导,但是,生成器返回按需产生结果的一个对象,而不是一次构建一个结果列表&oq=类似于列表推导,但是,生成器返回按需产生结果的一个对象,而不是一次构建一个结果列表

二、生成器函数

我们来看一个例子,使用生成器返回自然数的平方(注意返回的是多个值):

def gensquares(N):
    for i in range(N):
        yield i ** 2
for item in gensquares(5):
    print(item)

输出结果:
python
使用普通函数:

def gensquares(N):
    res=[]
    for i in range(N):
        res.append(i*i)
    return res
for item in gensquares(5):
    print(item)

可以看出,使用生成器函数代码量更少了。

三、生成器表达式

使用列表推导式,将会一次产生所有结果:

s1=[x**2 for x in range(5)]
print(s1)		#输出结果:[0, 1, 4, 9, 16]

将列表推导式的中括号,替换成圆括号,就是一个生成器的表达式:

>>>s1=(x**2+for+x+in+range(5))
>>>s1
>>>generator+object+at+0x00B2EC88>
>>>next(s1)
#0
>>>next(s1)
#1
>>>next(s1)
#4
>>>list(s1)
>#[9,16]

四、再看生成器

前面已经对生成器有了感性的认识,我们以生成器函数为例,再来深入探讨一下Python的生成器:

  • 语法上和函数类似: 生成器函数和常规函数几乎是一样的。它们都是使用def语句进行定义,差别在于,生成器使用yield语句返回一个值,而常规函数使用return语句返回一个值
  • 自动实现迭代器协议: 对于生成器,Python会自动实现迭代器协议,以便应用到迭代背景中(如for循环,sum函数)。由于生成器自动实现了迭代器协议,所以,我们可以调用它的next方法,并且,在没有值可以返回的时候,生成器自动产生StopIteration异常
  • 状态挂起: 生成器使用yield语句返回一个值。yield语句挂起该生成器函数的状态,保留足够的信息,以便之后从它离开的地方继续执行

五、案例

1.利用生成器生成可以无限取值的斐波拉切函数:

def fib():
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a + b

p = fib()
print([p.next() for i in xrange(101)])

2.生成器处理大日志文本文本:

def find_ip(path):
    for line in open(path):
        s = line.find('"Sogou web spider')
        if s >= 0:
            yield line[:s].strip()

p = find_ip("bigfile.txt")
p = list(set(list(p)))
for item in p:
    print item

print(time.time() - start_time, "seconds")

总结

本文深入浅出地介绍了Python中,一个容易被大家忽略的重要特性,即Python的生成器。在学习中,充分利用Python生成器,不但能够减少内存使用,还能够提高代码可读性。掌握生成器也是Python高手的标配。希望本文能够帮助大家理解Python的生成器。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值