一、生成器

1,生成器基本概念

生成器的实质是迭代器

迭代器:Iterator  内部同时包含了__iter__()和__next__()函数
可迭代对象:Iterable  内部包含__iter__()函数
迭代器的特点:(同时也是生成器特点)1,节省内存2,惰性机制3,不能反复只能向下执行

在Python中有三种方法来获取生成器:

1. 通过生成器函数

2. 通过各种推导式来实现生成器

3.通过数据的转换也可以获取生成器

示例:先看一个简单的函数:

def func():print("111")return 222ret = func()
print(ret)结果:
111
222

再将函数中的return换成yield变成生成器函数:

def func():print("111")yield 222ret = func()
print(ret)结果:
<generator object func at 0x10647a8e0>

可以看出结果是不一样的。由于函数中存在了yield,那么这个函数就是一个生成器函数。我们再执行这个函数的时候,就不再是函数的执行了,而是获取这个生成器。

因为生成器的本质是迭代器,所以我们可以直接执行__next__()以下生成器:

def func():print("111")yield 222gener = 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
teaTraceback (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__())  # 超出数量会报错# 结果:
# 0
# 1
# 2
# 3
# 4
# 5
# 6
# 7
# 8
# 9

生成器表达式与列表推导式的区别:
  1,列表推导式比较耗内存,一次性加载;而生成器表达式几乎不占用内存,使用的时候才分配和使用内存。

  2,得到的值不一样:列表推导式得到的是一个列表,生成器表达式获得的是一个生成器。

生成器的惰性求值:生成器只有在访问的时候才取值。

  

转载于:https://www.cnblogs.com/russellyoung/p/9671249.html

初识生成器与生成器表达式 Day12相关推荐

  1. 生成器和生成器表达式

    一 . 生成器 生成器就是迭代器 生成器的特点和迭代器一样. 1.省内存 2.惰性机制 3.只能向前 在python中有三种方式获取生成器 1.通过生成器函数 2.通过各种推导式来实现生成器 3.通过 ...

  2. python生成器yield原理_Python generator生成器和yield表达式详解

    前言 Python生成器(generator)并不是一个晦涩难懂的概念.相比于MetaClass和Closure等概念,其较为容易理解和掌握.但相对于程序结构:顺序.循环和分支而言其又不是特别的直观. ...

  3. 初学者python笔记(迭代器、生成器、三元表达式、列表解析、send()与yield())

    文章目录 迭代器与for循环的关系 1. 迭代器协议 2. 可迭代对象 3. for循环的本质 4. 强大的for循环机制 5. 迭代器如何工作的 6. while循环模拟for循环与迭代器的结合 7 ...

  4. python生成器表达式_python 生成器和生成器表达式

    1.生成器 生成器的本质就是迭代器 生成器的特点和迭代器一样.取值方式和迭代器一样(__next__(),send():给上一个yield传值) 生成器一般由生成器函数或者生成器表达式来创建 其实就是 ...

  5. Python中的yield关键字及表达式、生成器、生成器迭代器、生成器表达式详解

    文章目录 1. yield关键字及表达式.生成器.生成器迭代器.生成器表达式 1.1 yield关键字及表达式(yield expression) 1.1.1 yield关键字 1.1.2 yield ...

  6. 用python编写图片生成器_python生成器

    生成器 一.生成器 定义: 生成器与迭代器看成是一种.生成器的本质就是迭代器. 唯一的区别: 生成器是自己用python写代码构建的数据结构.迭代器都是(系统)提供的,或者转化而来的 获取生成器的三种 ...

  7. 自动论文生成器 python_python生成器

    python生成器 python高级特性 首先, 所有的生成器都是迭代器, 因为生成器完全实现了迭代器的接口. 在python中, 有两种不同的方式提供生成器: 1. 生成器表达式 2. 生成器函数 ...

  8. python生成器next_Python生成器生成next,python,yieldnext

    在实践keras网络模型的时候,发现keras fit_generator与flow_from_directory函数均有关于生成器的频繁使用:因此在本文中对其进行总结. Python 之所以要提供这 ...

  9. python小说自动生成器_python- generator生成器

    什么是生成器? 通过列表生成式,我们可以直接创建一个列表,但是,受到内存限制,列表容量肯定是有限的,而且创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后 ...

最新文章

  1. python怎么输入代码-教你如何将自己的脚本代码放到服务器上运行
  2. MyBatisPlus(基于starter和Bean方式)
  3. erp 维护费 要交吗_ERP系统维护费
  4. python今日内容_python笔记15
  5. ubuntu20有道词典亲测安装记录
  6. python 的基础 学习 第六天 基础数据类型的操作方法 字典
  7. day04【后台】角色维护
  8. CCCC-GPLT L1-040. 最佳情侣身高差 团体程序设计天梯赛
  9. python绘制小猪佩奇
  10. v2ex热帖:面了几个程序员(3-5年),发现他们对MySQL的distinct关键字有误解......
  11. RobotFramework与Eclipse集成
  12. linux虚拟化cpu的绑定,为虚拟机vCPU绑定物理CPU
  13. 宏电GPRS DTU H7210调试报告之DEMO测试
  14. Laravel之数据库操作与Eloquent模型使用总结
  15. 【MySQL篇】第三篇——表的操作
  16. 不可多得的MBA相关书籍推荐
  17. 教你什么时候用Vue计算属性!!!
  18. easyui-serchbox组件的使用
  19. Ray----Tune(2):Tune的用户指南
  20. 我给同事制定的英语学习计划

热门文章

  1. Too many open files 问题
  2. spring-in-action-mvc-jdbc搭建工程
  3. 直接在低版本IE6/7/8浏览器中使用HTML5的audio和video标签播放视频音频的办法
  4. cocos2dx 圆盘抽奖_【cocos2dx 3.3 lua】06 抽奖转盘效果
  5. Linux 打包 压缩 解压缩 命令
  6. (08)System Verilog 队列详解
  7. FPGA常用FIFO简介
  8. 1014.修改clion的工具链
  9. STM32F103_DDWG窗口看门狗
  10. STM32 IIC详解