初识生成器与生成器表达式 Day12
一、生成器
1,生成器基本概念
生成器的实质是迭代器
- 迭代器:Iterator 内部同时包含了__iter__()和__next__()函数
- 可迭代对象:Iterable 内部包含__iter__()函数
- 迭代器的特点:(同时也是生成器特点)
- 1,节省内存
- 2,惰性机制
- 3,不能反复只能向下执行
在Python中有三种方法来获取生成器:
1. 通过生成器函数
2. 通过各种推导式来实现生成器
3.通过数据的转换也可以获取生成器
示例:先看一个简单的函数:
- def func():
- print("")
- return 222
- ret = func()
- print(ret)
- 结果:
- 111
- 222
再将函数中的return换成yield变成生成器函数:
- def func():
- print("")
- yield 222
- ret = func()
- print(ret)
- 结果:
- <generator object func at 0x10647a8e0>
可以看出结果是不一样的。由于函数中存在了yield,那么这个函数就是一个生成器函数。我们再执行这个函数的时候,就不再是函数的执行了,而是获取这个生成器。
因为生成器的本质是迭代器,所以我们可以直接执行__next__()以下生成器:
- def func():
- print("")
- yield 222
- gener = func() # 这个时候函数不会执行,只是获取到生成器
- ret = gener.__next__() # 函数执行,yield和return的作用一样,返回数据
- print(ret)
- 结果:
- 111
- 222
所以,yield和return的效果是一样的,都是返回数据,但还是有很大区别的:
yield是分段来执行一个函数;return是直接停止执行函数
2,生成器的send()方法:
send()和__next__()一样都可以让生成器执行到下一个yield
- def eat():
- print("meat")
- a = yield "milk"
- print('baozi', a)
- b = yield 'zhou'
- print('guobaorou', b)
- yield 'tea'
- gen = eat()
- ret = gen.__next__()
- print(ret)
- ret = gen.__next__()
- print(ret)
- ret = gen.send("MIANBAO") # 给上一个yield传值
- print(ret)
- ret = gen.send("DANGAO") # 给上一个yield传值
- print(ret)
- 结果:
- meat
- milk
- baozi None
- zhou
- guobaorou MIANBAO
- tea
- Traceback (most recent call last):
- ret = gen.send("DANGAO") # 给上一个yield传值
- StopIteration
send()和__next__():
1. send和next都是让生成器向下走一次
2. send可以给上一个yield的位置传递值,不能给最后一个yield发送值。也不能在第一次执行生成器代码的时候不能使用send()
3,使用for循环
- def func():
- yield "a"
- yield "b"
- yield "c"
- gen = func()
- for el in gen:
- print(el)
- # 结果:
- # a
- # b
- # c
使用for循环的话会获取内部所有的元素
二、列表推导式,生成器表达式以及其他推导式
1,列表推导式
常用写法:[结果 for循环 if筛选]
筛选模式:[结果 for 变量 in 可迭代对象 if 条件]
练习题:
- # (1)创建列表:[1,3,5,7,9,...99]
- l2 = [i for i in range(1,100) if i % 2 == 1] # [结果 for循环 if筛选]
- print(l2)
- # [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99]
- # 列表推导式
- # (1) 过滤掉长度小于3的字符串列表,并将剩下的转换成大写字母
- lst = ['hello', 'world', 'hh', 'old', 'boy', 'H']
- l1 = [i.upper() for i in lst if len(i) >= 3]
- print(1, l1)
- # (2) 求(x,y)其中x是0-5之间的偶数,y是0-5之间的奇数组成的元祖列表
- l2 = [(x, y) for x in range(5) if x % 2 == 0 for y in range(5) if y % 2 == 1]
- # l2 = list(zip([x for x in range(6) if x % 2 == 0], [y for y in range(6) if y % 2 == 1]))
- print(2, l2)
- # (3) 求M中3,6,9组成的列表M = [[1,2,3],[4,5,6],[7,8,9]]
- M = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
- l3 = [el[2] for el in M]
- print(3, l3)
- # (4) 求出50以内能被3整除的数的平方,并放入到一个列表中。
- l4 = [i*i for i in range(1, 50) if i % 3 == 0]
- print(4, l4)
- l4_1 = [i for i in range(1, 50) if i % 3 == 0 and i*i < 50]
- print(l4_1)
- # (6) 构建一个列表:[(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]
- # l6 = [(x, y) for x in range(6) for y in range(1, 7)]
- l6 = [(x, x+1) for x in range(6)]
- print(6, l6)
- # (7) 构建一个列表:[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
- l7 = [i for i in range(0, 19, 2)]
- print(7, l7)
- # (8)有一个列表l1 = ['alex', 'WuSir', '老男孩', '太白']将其构造成这种列表['alex0', 'WuSir1', '老男孩2', '太白3']
- ll = ['alex', 'WuSir', '老男孩', '太白']
- l8 = [v+str(i) for i, v in enumerate(ll)]
- print(8, l8)
- # l8 = []
- # for i,v in enumerate(ll):
- # v = v+str(i)
- # print(v,i)
- # (9)有以下数据类型:
- x = {
- 'name': 'alex',
- 'Values': [
- {'timestamp':1517991992.94,
- 'values':100,},
- {'timestamp': 1517992000.94,
- 'values': 200,},
- {'timestamp': 1517992014.94,
- 'values': 300,},
- {'timestamp': 1517992744.94,
- 'values': 350},
- {'timestamp': 1517992800.94,
- 'values': 280}
- ], }
- # 将上面的数据通过列表推导式转换成下面的类型:
- # [[1517991992.94, 100], [1517992000.94, 200], [1517992014.94, 300], [1517992744.94, 350], [1517992800.94, 280]]
- l9 = [[el['timestamp'], el['values']] for el in x['Values']]
- print(9, l9)
- # 结果:
- 1 ['HELLO', 'WORLD', 'OLD', 'BOY']
- 2 [(0, 1), (0, 3), (2, 1), (2, 3), (4, 1), (4, 3)]
- 3 [3, 6, 9]
- 4 [9, 36, 81, 144, 225, 324, 441, 576, 729, 900, 1089, 1296, 1521, 1764, 2025, 2304]
- [3, 6]
- 6 [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]
- 7 [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
- 8 ['alex0', 'WuSir1', '老男孩2', '太白3']
- 9 [[1517991992.94, 100], [1517992000.94, 200], [1517992014.94, 300], [1517992744.94, 350], [1517992800.94, 280]]
- # (5) 寻找名字中带有两个e的人的名字
- names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven','Joe'],
- ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']]
- # l5 = []
- # for i in range(len(names)):
- # for j in names[i]:
- # if j.count('e') >= 2:
- # l5.append(j)
- l5 = [j for i in range(len(names)) for j in names[i] if j.count('e') >= 2]
- print(l5)
- # 主要注意str.count()的运用,查找字符串数量
2,生成器表达式:
语法与列表推导式基本上是一样的。只是把 [] 替换成 {}
- gen = (i for i in range(10)) # 生成表达式
- print(gen.__next__())
- print(gen.__next__())
- print(gen.__next__())
- print(gen.__next__())
- print(gen.__next__())
- print(gen.__next__())
- print(gen.__next__())
- print(gen.__next__())
- print(gen.__next__())
- print(gen.__next__())
- # print(gen.__next__()) # 超出数量会报错
- # 结果:
- #
- #
- #
- #
- #
- #
- #
- #
- #
- #
生成器表达式与列表推导式的区别:
1,列表推导式比较耗内存,一次性加载;而生成器表达式几乎不占用内存,使用的时候才分配和使用内存。
2,得到的值不一样:列表推导式得到的是一个列表,生成器表达式获得的是一个生成器。
生成器的惰性求值:生成器只有在访问的时候才取值。
初识生成器与生成器表达式 Day12的更多相关文章
- python day12 ——1.生成器2.生成器表达式 3.列表推导式
一.生成器 什么是生成器. 生成器实质就是迭代器. 在python中有三种方式来获取生成器: 1. 通过生成器函数. 2. 通过各种推导式来实现生成器 . 3. 通过数据的转换也可以获取生成器. 1. ...
- Python学习笔记(4):容器、迭代对象、迭代器、生成器、生成器表达式
在了解Python的数据结构时,容器(container).可迭代对象(iterable).迭代器(iterator).生成器(generator).列表/集合/字典推导式(list,set,dict ...
- python全栈开发-前方高能-生成器和生成器表达式
python_day_13 今日主要内容1. 生成器和生成器函数生成器的本质就是迭代器生成器的三种创建办法: 1.通过生成器函数 2.通过生成器表达式创建生成器 3.通过数据转换 生成器函数: 函数中 ...
- Python入门-生成器和生成器表达式
昨天我们说了迭代器,那么和今天说的生成器是什么关系呢? 一.生成器 什么是生成器?说白了生成器的本质就是迭代器. 在Python中中有三种方式来获取生成器. 1.通过生成器函数 2.通过各种推导式来实 ...
- python基础之生成器,三元表达式,列表生产式
生成器 1.什么是生成器? 在函数内但凡出现yield关键字,再调用函数就不会执行函数体代码,会返回一个值,该值称为生成器. 生成器的本质就是迭代器. 2.为什么要用生成器? 生成器是一种自定义迭代器 ...
- python基础之生成器、三元表达式、列表生成式、生成器表达式
生成器 生成器函数:函数体内包含有yield关键字,该函数执行的结果是生成器,生成器在本质上就是迭代器. def foo(): print('first------>') yield 1 pri ...
- Python生成器、三元表达式、列表生成式、字典生成式、生成器表达式
什么是生成器:只要函数内部包含有yield关键字,那么函数名()的到的结果(生成器地址)就是生成器,再调用函数不会执行函数内部代码这个生成器本身有 _iter_ he _next_功能(即生成器 ...
- 2018.8.13 python中生成器和生成器表达式
主要内容: 1.生成器和生成器函数 2.列表推导式 一.生成器 生成器是指就是迭代器,在python中有三种方式来获取生成器: 1.通过生成器函数 2.通过各种推导式来实现生成器 3.通过数据的转换也 ...
- Python的生成器和生成器表达式
一,生成器和生成器表达式 什么是生成器,生成器实质就是迭代器,在python中有三种方式来获取生成器: 1. 通过生成器函数 和普通函数没有区别,里面有yield的函数就是生成器函数,生成器函数在执行 ...
随机推荐
- JVM内存模型你只要看这一篇就够了
JVM内存模型你只要看这一篇就够了 我是一只孤傲的鱼鹰 让我们不厌其烦的从内存模型开始说起:作为一般人需要了解到的,JVM的内存区域可以被分为:线程栈,堆,静态方法区(实际上还有更多功能的区域,并且这 ...
- tyvj/joyoi 1043 表达式计算4
这题怎么这么毒瘤... 一开始我想转后缀表达式来计算,后来发现有负数...弃疗. 递归求解又发现会有多余括号,我觉得不行... 实在是毒瘤啊! #include <cstdio> #inc ...
- 跟我一起写一个hello-world react组件并发布到npm
第一步:初始化我们的配置 $ mkdir react-hello-world $ cd react-hello-world/ $ npm init -y 修改我们的package.json文件 //p ...
- jasperreport
我们的报表要用FusionCharts.jasperreport
- JAVA 微信支付 native方式
最近做了一个微信native方式支付的demo,整理一下. 首先到微信公众号官网阅读开发文档,虽然文档对于java没有例子,但是也可以作参考.https://pay.weixin.qq.com/wik ...
- SQLServer 游标详解
一.用到的数据 CREATE TABLE [dbo].[XSB]( ) NOT NULL, ) NOT NULL, [性别] [bit] NULL, [出生时间] [date] NULL, ) NUL ...
- CentOS 6.x 最小化安装推荐安装的依赖包和修改内核参数
CentOS 6.x 最小化安装推荐安装的依赖包 我在日常工作中,新建的xenserver的虚拟机,CentOS release 6.9 (Final)操作系统,采用最小化安装,后续很多操作需要各种依 ...
- fiddler模拟返回
先把正常的请求响应报文保存为文件,操作方法为选中对应请求>右键> save >reponse>entire response 点击改请求,点击右侧autoresponder,点 ...
- Linux下查看线程数的几种方法汇总
Linux下查看线程数的几种方法汇总 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Linux下查看某个进程的线程数量 pstree命令以树状图显示进程间的关系(display ...
- sql关联更新
/****** Script for SelectTopNRows command from SSMS ******/SELECT * FROM [LFBMP.Operating].[dbo].[Sh ...