python生成器 图片分类_Python内置类型(6)——生成器

上节内容说到Python的for语句循环本质上就是通过调用Iterable可迭代对象的__iter()__方法获得一个Iterator迭代器对象,然后不断调用Iterator迭代器对象__next()__方法实现的。Iterator迭代器对象则是一个需要实现__iter__()和__next__()两个迭代器协议方法的对象。python中生成器提供了一种方便的方法来实现迭代器协议,而不需要必须实现__iter__()和__next__()两个迭代器协议方法。

生成器的定义方式有两种,一种是调用生成器函数,一种是使用生成器表达式语法。

调用生成器函数

生成器函数是指在函数体中使用yield表达式仅返回结果的函数。yield表达式仅在定义生成器函数时使用,因此只能用在函数定义的主体中。在函数体中使用yield表达式会使该函数成为生成器函数。当生成器函数被调用时,它返回一个称为生成器的迭代器,该迭代器由python自动生成。然后,生成器控制了生成器函数的执行。因为返回的生成器是一个迭代器,所以生成器函数的执行结果也就可以被循环。当生成器的的__next__方法被调用时,生成器函数的函数体内的语句开始执行,执行进行到第一个yield表达式时,立即将yield表达式的结果返回给生成器的调用者,同时将生成器函数内部的状态挂起。即保持生成器函数的执行进度,和生成器函数内的局部状态:包括局部变量的当前绑定,指令指针,内部计算栈和任何异常处理的状态。当生成器的再次调用__next__方法来时,生成器函数恢复执行,并再次执行到yield表达式返回结果再保持状态,直到无法再执行到yield表达式。此时生成器自动抛出StopIteration异常。

我们先定义一个简单生成器函数,函数功能返回数字0-9的平方数

# 生成器函数,功能返回数字0-9的平方数

>>> def squares():

for i in range(10):

yield i**2

# 使用return关键字是普通函数,使用yield关键字函数变成了生成器函数

使用参数g接收调用生成器函数squares的结果,然后分别在shell查看squares和g这两个变量的类型

>>> g = squares()

#查看squares对象类型

>>> squares

#查看g对象类型

>>> g

从上面可以看出变量squares是函数类型,变量g是generator类型对象,generator从字面的理解上就是生成器类型。根据上一节迭代器中提到的知识,从collection模块引入Iterator的抽象基类,验证下generator类型是不是上面说的迭代器类型。

>>> from collections import Iterator

>>> isinstance(g,Iterator)

True

验证成功,说明生成器函数的执行结果确实是生成器,一种特殊的迭代器。

>>> for i in g:

print (i)

0

1

4

9

16

25

36

49

64

81

生成器表达式

除了使用生成器函数可以得到生成器,还可以生成器表达式得到生成器表达式。生成器表达式本身看起来像列表推到, 但不是用方括号而是用圆括号包围起来:

>>> g2 = (x**2 for x in range(10))

>>> g2

at 0x0359AFC0>

>>> t = (1,2,3,4,5)

>>> g3 = (x**2 for x in t)

>>> g3

at 0x007F6180>

验证:

>>> isinstance(g2,Iterator)

True

>>> isinstance(g3,Iterator)

True

使用:

>>> for i in g2:

print(i)

0

1

4

9

16

25

36

49

64

81

>>> for i in g3:

print(i)

1

4

9

16

25

和普通迭代器相比,生成器不单简化了迭代器的定义,还在使用效率上有提升。因为生成器在循环时,生成器函数每次只会返回一个结果,然后保持内部状态,所以生成器占用的内存是很小的。以下两个测试结果,第一个直接抛出MemoryError异常,第二个只能正确计算出结果。

# 全部数据先加载在1个列表上面,内存占用高

>>> s1 = sum([i for i in range(100000000)])

Traceback (most recent call last):

File "", line 1, in

s1 = sum([i for i in range(100000000)])

File "", line 1, in

s1 = sum([i for i in range(100000000)])

MemoryError

# 数据几乎不占内存

>>> s2 = sum((i for i in range(100000000)))

>>> s2

4999999950000000

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/559426.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java 把方法当参数传递_java 中 如何将“一个类的方法 ”作为参数传到“另一个类的方法”中...

展开全部在java中这是没有办法做到的,因e5a48de588b662616964757a686964616f31333337396336为java不是函数式编程语言,不过可以通过传递一个接口来实现。下面解说java如何模拟:先定义一个接口:interface MethodInterface{//这个方法假如就是你…

轮询数据库 java_谁做过定时任务,轮询查询数据。

一、增加所依赖的JAR包1、增加Spring的Maven依赖org.springframeworkspring-webmvc3.0.5.RELEASE2、增加Quartz的Maven依赖org.quartz-schedulerquartz1.8.4二、增加定时业务逻辑类public class ExpireJobTask {/** Logger */private static final Logger logger LoggerFactor…

arcgis制作空间变化图怎么做_听说如果做数据分析不用GIS,会被开?

Q你有没有遇到这样的情况?身边的同事或同学经常说什么高程图、坡向图、坡度图、生态水文图、热力密度图、大数据算法,而自己却一无所知,心里感到特别的慌啊。文末附ArcGIS最新版及超强数据神器 很多人会说,“设计师是感性的&#…

仅完成部分的readprocessmemory或write_王者荣耀:三种李小龙获取方式!无需完成任务、28号即可兑换...

哈喽大家好!我是你们的小菜鸡“荣耀急先锋”王者荣耀五周年庆限定皮肤李小龙活动已经开始啦!大家有参加了吗?或者说对这个活动不太理解,针对这些小伙伴菜鸡今天就简单的跟大家讲讲李小龙皮肤活动的规则,让我们一起看看…

uuid java 重复_Java中使用UUID工具类生成唯一标志防止重复

import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import java.security.SecureRandom;import java.util.Random;import java.util.concurrent.ThreadLocalRandom;/*** 提供通用唯一识别码(universally unique identifier)(UUID)实现**/publ…

优秀ppt作品范例_首次公开|锐普的内部PPT配色库

每次发锐普的作品,总会有小伙伴们问:这么漂亮的配色到底是怎么做的呢?今天我在锐普内部的资源库发现一个超级宝贝——锐普内部的PPT配色库,1008张超精彩PPT配色范例。我的天,原来设计部竟然还藏着这种宝贝!…

java get null_java 获取对象中为null的字段实例代码

下面一段简单的代码给大家分享java 获取对象中为null的字段,具体代码如下所述:private static String[] getNullPropertyNames(Object source) {final BeanWrapper src new BeanWrapperImpl(source);java.beans.PropertyDescriptor[] pds src.getPrope…

linux rz sz 安装_Windows与Linux文件传输之lrzsz工具

请关注本头条号,每天坚持更新原创干货技术文章如需学习视频,请查看本头条号简介,免费在线观看学习视频1. lrzsz工具简介Windows向Linux传输文件,最简单的方法是使用rz和sz命令。当然用有其他的方法,比如通过ssh(winscp…

java游戏重新开始_问题1:java问题--某局小游戏结束后怎么重新开始?

有个问题,想了好久没解决,上网找了下,貌似也没找到好的解决方法(谷歌暂时没上去),现在这里写下来吧:最近在写一个五子棋的小游戏,也算是刚刚开始java入门的一个作品了吧,刚刚完成到人人对战(当然…

python编码器下载_Python Code128编码器

这是一个可以接受的答案,所以我将原始代码留在下面。但我更喜欢这种精致。在def list_join(seq): Join a sequence of lists into a single list, much like str.joinwill join a sequence of strings into a single string.return [x for sub in seq for x in sub]…

java url后面带sessionid_Spring Mvc boot解决静态url带jsessionid问题

1.jsessionid是什么?Jsessionid只是tomcat的对sessionid的叫法,其实就是sessionid;在其它的容器也许就不叫jsessionid了。2.那么有什么问题?首先这是一个保险措施 因为Session默认是需要Cookie支持的,但有些客户浏览器是关闭Cook…

python二分查找算法_如何使用python的二分查找算法

如何使用python的二分查找算法发布时间:2020-11-18 09:27:29

retryexec.java 94_解决feign调用接口不稳定的问题

我就废话不多说了,大家还是直接看代码吧~Caused by: java.net.SocketException: Software caused connection abort: recv failedat java.net.SocketInputStream.socketRead0(Native Method)at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)a…

lua pcall 返回值_Redis和Lua整合

前面我们已经介绍完了Redis相关的理论知识,从本篇开始我们介绍一些Redis相关的时机应用。比如:Redis整合LuaRedis的消息模式Redis实现分布式锁常见的缓存问题我们先从Redis整合Lua的使用开始。lua是一种轻量小巧的脚本语言,用标准C语言编写并…

java 异步调用webapi_Async Await异步调用WebApi

先铺垫一些基础知识 在 .net 4.5中出现了 Async Await关键字,配合之前版本的Task 来使得开发异步程序更为简单易控。 在使用它们之前 我们先关心下 为什么要使用它们。好比 一个人做几件事,那他得一件一件的做完,而如果添加几个人手一起帮着…

哲学家就餐问题python_哲学家就餐-同步问题解析-python

五个哲学家吃五盘通心粉,由于通心粉很滑,所以必须要拿起左右两边的叉子才能吃到。叉子的摆放如图所示。那么问题来了:能为每一个哲学家写一段描述其行为的程序,保证不会出现死锁。解法1:让他等待能够使用的时候,然后去…

java compare equla_Java中的equals,==,compareTo和compare的比较

Java中的equals(),,compareTo()和compare()首先只有可以用作两个基本类型数据之间的比较,当然是值比较。当用作两个对象比较时,比较的是对象引用,而不是值比较。其次任何对象都可以调用.equals()方法,因为这是从Object类继承下来的…

百度相关搜索软件_不太热门的办公神器软件篇搜索相关

这次介绍两个windows平台超好用的搜索神器——listary和everything全文阅读约需3分钟在工作中,虽然大部分文件都会分门别类地放在对应的文件夹中,但总有一些放完就忘了在哪或是层级过深打开不便的情况。这两个搜索神器完美地解决了找不到文件且windows自…

java摘要_java 摘要

packagecom.aarony.test;importjava.io.IOException;importjava.security.MessageDigest;importsun.misc.BASE64Decoder;importsun.misc.BASE64Encoder;public classDigestDemo {/**** 此方法描述的是:base64 解码**author: Aarony*version: 2018年6月20日 下午9:16…

python的装饰器、迭代器、yield_python装饰器,迭代器,生成器,协程

python装饰器[1]首先先明白以下两点#嵌套函数defout1():definner1():print(1234)inner1()#当没有加入inner时out()不会打印输出1234,当前层级也就是作用域下必须调用函数才能引用out1()#函数作用域defout2():a aaadefinner2():a bbbprint(a)inner2()print(a)out2()#当相同变量处…