Python生成器定义与简单用法实例分析

这篇文章主要介绍了python生成器定义与简单用法,结合实例形式较为详细的分析了python生成器的概念、原理、使用方法及相关操作注意事项,需要的朋友可以参考下

本文实例讲述了Python生成器定义与简单用法。分享给大家供大家参考,具体如下:

一、什么是生成器

在Python中,由于受到内存的限制,列表容量肯定是有限的。例如我们创建一个包含一亿个元素的列表,Python首先会在内存中开辟足够的空间来存储这个包含一亿个元素的列表,然后才允许用户去使用这个列表,这就可能会导致以下问题:

  1、内存中没有足够的内存空间开存储这个列表,从而导致列表无法创建

立即学习“Python免费学习笔记(深入)”;

  2、即使列表成功创建,然而仍会消耗很长的时间,导致程序效率低下

  3、若用户只想访问列表前面的几个元素,则后面列表绝大多数元素占用的空间就都白白浪费了

为了有效解决以上的问题,Python中引入了一种“一边循环,一边计算”的新机制,即当用户需要使用某个对象时,Python才根据事先设计好的规则开辟内存空间创建这个对象供用户使用,而不是像列表一样事先将所有的对象都创建完毕之后再提供给用户使用。这种机制在Python中成为生成器(generator)。

二、生成器的创建

A、生成器推到式

与列表推到式类似,只不过生成器推导式使用()而非[],并且最终返回的是生成器而非列表

g=((i+2)**2 for i in range(2,30)) #g是一个生成器print(g) #g为空,里面包含任何元素

登录后复制

运行结果:

B、yield关键字

在一个函数定义中包含yield关键字,则这个函数就不再是一个普通的函数,而是一个生成器(generator)

[说明]:yield指令可以暂停一个函数并返回其中间结果,使用该指令的函数将保存执行环境,并在必要时恢复

def fib(max):  n,a,b=0,0,1  while n

运行结果:

[注]:普通函数和变成生成器的函数的不同:

普通函数是顺序执行的,遇到return或是最后一行函数语句就返回。而变成生成器的函数在每次调用__next__()方法时执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行

f=fib(6)print(f)print(f.__next__())print(f.__next__())print('暂停一下')print(f.__next__())print(f.__next__())

登录后复制

运行结果:

1
1
暂停一下
2
3

三、生成器方法(参考:伯乐在线)

1.close()方法:手动关闭生成器函数,后面的调用会直接返回StopIteration异常

def func():  yield 1  yield 2  yield 3g=func()g.__next__()g.close() #手动关闭生成器g.__next__() #关闭后,yield 2和yield 3语句将不再起作用

登录后复制

运行结果:

Traceback (most recent call last):
  File "E:py3DemoHellogeneratorDemo.py", line 9, in
    g.__next__() #关闭后,yield 2和yield 3语句将不再起作用
StopIteration

2.__next__()方法:返回生成器的下一次调用

def func():  n=1  for i in range(3):    yield n    n+=1c=func()a1=c.__next__()a2=c.__next__()a3=c.__next__()

登录后复制

[流程解释]:

对于普通的生成器,第一个__next__()方法的调用相当于启动生成器,此时会从生成器函数的第一行开始执行,直到第一次执行完yield语句(第四行)后,跳出生成器函数。

当调用第二个__next__()方法后,会重新进入生成器函数,并从yield语句的下一条语句(第五行)开始执行,直到重新运行到yield语句,执行后再次跳出生成器函数。

后面的__next__()方法调用以此类推

3.send()方法:接受外部传入的一个变量,并根据变量内容计算结果返回到生成器函数中

[注]:

(1)send()方法和__next__()方法相似,区别在于send()方法可以传递给yield表达式值,而__next__()方法不能传递特定的值,只能传递None给yield表达式,因此可以将generator.__next__()理解为generator.send(None)

(2)第一次调用生成器函数时,必须使用__next__()语句或是send(None),不能使用send发送一个非None的值给生成器函数,否则会出错,因为没有yield语句来接收这个值

def gen():  value=0  while True:    receive=yield value    if receive=='end':      break    value='Got:%s' %receiveg=gen()print(g.__next__()) #或是print(g.send(None)),从而启动生成器print(g.send('aaa'))print(g.send(3))print(g.send('end'))

登录后复制

运行结果:

0
Got:aaa
Got:3
Traceback (most recent call last):
  File "E:py3DemoHellogeneratorDemo.py", line 13, in
    print(g.send('end'))
StopIteration

[流程解释]:

a.通过g.send(None)或g.__next__()启动生成器函数,并执行到第一个yield语句结束的位置并将函数挂起。此时执行完了yield语句,但是没有给receive赋值,因此yield value会输出value的初始值0

b.g.send('aaa')先将字符串‘aaa'传入到生成器函数中并赋值给receive,然后从yield语句的下一句重新开始执行函数(第五句),计算出value的值后返回到while头部开始新一轮的循环,执行到yield value语句时停止,此时yield value会输出‘Got:aaa',然后挂起

c.g.send(3)重复步骤b,最后输出结果为‘Got:3'

d.g.send('end')会使程序执行break然后跳出循环,从而函数执行完毕,得到StopIteration异常

4.throw()方法:向生成器发送一个异常。

def gen():  while True:    try:      yield 'normal value' #返回中间结果,此处的yield和return的功能相似      yield 'normal value2'      print('I am here')    except ValueError:      print('We got ValueError')    except Exception:      print('Other errors')      breakg=gen()print(g.__next__())print(g.throw(ValueError))print(g.__next__())print(g.throw(TypeError))

登录后复制

运行结果:

Traceback (most recent call last):
  File "E:py3DemoHellogeneratorDemo.py", line 17, in
    print(g.throw(TypeError))
StopIteration
normal value
We got ValueError
normal value
normal value2
Other errors

[解释]:

a.print(g.__next__())会输出normal value,并停在yield 'normal value2'之前

b.由于执行了g.throw(ValueError),所以回跳过后续的try语句,即yield ‘normal value2'不会执行,然后进入到except语句,打印出‘We got ValueError'。之后再次进入到while语句部分,消耗一个yield,输出normal value

c.print(g.__next__())会执行yield ‘normal value2'语句,并停留在执行完该语句后的位置

d.g.throw(TypeError)会跳出try语句,因此print('I am here')不会被执行,然后打印‘Other errors',并执行break语句跳出while循环,然后到达程序结尾,打印StopIteration异常的信息

四、生成器的运用

import timedef consumer(name):  print('%s准备吃包子啦!' %name)  while True:    baozi=yield #接收send传的值,并将值赋值给变量baozi    print('包子[%s]来了,被[%s]吃了!' %(baozi,name))def producer(name):  c1=consumer('A') #把函数变成一个生成器  c2=consumer('B')  c1.__next__()#调用这个方法会走到yield处暂时返回  c2.__next__()  print('开始准备做包子啦!')  for i in range(10):    time.sleep(1)    print('做了一个包子,分成两半')    c1.send(i)    c2.send(i)producer('Tomwenxing')

登录后复制

运行结果:

A准备吃包子啦!
B准备吃包子啦!
开始准备做包子啦!
做了一个包子,分成两半
包子[0]来了,被[A]吃了!
包子[0]来了,被[B]吃了!
做了一个包子,分成两半
包子[1]来了,被[A]吃了!
包子[1]来了,被[B]吃了!
做了一个包子,分成两半
包子[2]来了,被[A]吃了!
包子[2]来了,被[B]吃了!
做了一个包子,分成两半
包子[3]来了,被[A]吃了!
包子[3]来了,被[B]吃了!
做了一个包子,分成两半
包子[4]来了,被[A]吃了!
包子[4]来了,被[B]吃了!
做了一个包子,分成两半
包子[5]来了,被[A]吃了!
包子[5]来了,被[B]吃了!
做了一个包子,分成两半
包子[6]来了,被[A]吃了!
包子[6]来了,被[B]吃了!
做了一个包子,分成两半
包子[7]来了,被[A]吃了!
包子[7]来了,被[B]吃了!
做了一个包子,分成两半
包子[8]来了,被[A]吃了!
包子[8]来了,被[B]吃了!
做了一个包子,分成两半
包子[9]来了,被[A]吃了!
包子[9]来了,被[B]吃了!

相关推荐:

Python迭代器定义与简单用法分析

Python装饰器原理与用法分析

以上就是Python生成器定义与简单用法实例分析的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2262839.html

(0)
上一篇 2025年2月27日 07:13:20
下一篇 2025年1月4日 00:01:07

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • 计算机编程语言有多少种

    目前已知有数百种计算机编程语言,并仍在不断发展。根据不同的标准,编程语言可分为范式(如结构化、面向对象)、用途(如通用、特定领域)和编写方式(如编译型、解释型)。最流行的编程语言包括 Python、C、Java、C++、C#、Visual …

    2025年2月27日
    000
  • 计算机语言有哪些各有什么特点

    计算机语言是人机交互的媒介,分为低级语言(二进制、汇编)和高级语言(C/C++、Java、Python、JavaScript、Swift)。选择语言时需考虑任务要求、性能、开发者能力和平台兼容性。 计算机语言:类型和特点 什么是计算机语言?…

    2025年2月27日
    200
  • python 实现在txt指定行追加文本的方法

    这篇文章主要介绍了关于python 实现在txt指定行追加文本的方法,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 如下所示: fp = file(‘data.txt’)lines = []for line in fp:  …

    编程技术 2025年2月27日
    200
  • Python 实现在文件中的每一行添加一个逗号

    这篇文章主要介绍了关于python 实现在文件中的每一行添加一个逗号,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 步骤1:读取每行(每行的类型是str) 步骤2:对每行列表化 步骤3:弹出每行的/n两个字符 步骤4:追加,…

    编程技术 2025年2月27日
    200
  • 电脑编程用什么软件比较好

    选择编程软件应考虑编程语言、平台、功能和价格。推荐的软件包括:IDE:Visual Studio Code、PyCharm、IntelliJ IDEA代码编辑器:Sublime Text、Atom、Notepad++文本编辑器:Vi、Ema…

    2025年2月27日
    200
  • python 把文件中的每一行以数组的元素放入数组中的方法

    这篇文章主要介绍了关于python 把文件中的每一行以数组的元素放入数组中的方法,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 有时候需要把文件中的数据放入到数组中,这里提供了一种方法,可以根据文件结尾的标记进行数据拆分,然…

    编程技术 2025年2月27日
    200
  • 电脑编程语言有日文的吗怎么弄

    电脑编程语言支持日文编程,包括 Ruby、Python 和 JavaScript 等。使用日文编程语言时,需要安装日文支持,使用日文编码,使用日文变量名和函数名,使用双引号或单引号引用日文文本,并添加日文注释。 电脑编程语言有日文的吗? 答…

    2025年2月27日
    200
  • 电脑编程的基本语言有哪些

    最常用的基本编程语言包括:1. Python;2. Java;3. C;4. C++;5. JavaScript;6. SQL。这些语言因其易用性、可移植性、面向对象特性和与数据库交互的能力而被广泛采用。此外,还有其他流行的基本语言,如 V…

    2025年2月27日
    200
  • Python绘制3D图形

    这篇文章主要介绍了关于python绘制3d图形,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 3D图形在数据分析、数据建模、图形和图像处理等领域中都有着广泛的应用,下面将给大家介绍一下如何使用python进行3D图形的绘制,…

    2025年2月27日 编程技术
    200
  • 全国最火的编程语言是什么

    全国最火的编程语言是 Python,其优势包括易于学习、多功能、丰富的库、跨平台兼容性和社区支持。Python 被广泛应用于数据科学、机器学习、Web 开发、自动化和云计算领域。 全国最火的编程语言 目前,全国最火的编程语言是 Python…

    2025年2月27日
    200

发表回复

登录后才能评论