Python——生成器&推导式
生成器
生成器的本质就是迭代器,那么还为什么有生成器呢,两者唯一的不同就是迭代器都是Python给你提供能够的已经写好的工具或者通过数据转化得来的。而生成器是需要我们自己用Python代码构建的工具。
生成器的构建方式:
在python中有两种方式来创建生成器:
通过生成器函数
通过生成器推导式
生成器函数:
首先我们来一个简单的函数结构:
- def func():
- print('111')
- return 222
- result = func()
- print(result)
没得问题,那么在看看生成器函数是啥样的。
- def func():
- print('111')
- yield 222
- result = func()
- print(result)
- # <generator object func at 0x000002980E331C10>
以这样打印,就给打印了个这东西。这意思是,当函数看到返回值是yield的时候,就说明这个函数时一个生成器函数。返回的是一个生成器。那么要调用怎么办呢。
- def func():
- print('111')
- yield 222
- result = func() #这会还不会调用,而是获取到一个生成器
- ret = result.__next__() #这个时候函数才会被执行。
- print(ret) #而且yield会将func返回的222给ret
就是将return该成yield,再用next来提取就成了。
还有yield可以写多个,一个next对应一个yield,next多了就会报错。
- def func():
- print('111')
- yield 222
- print('222')
- yield 333
- print('333')
- yield 444
- result = func()
- print(next(result))
- print(next(result))
- print(next(result))
发现它的用处了吗~?? 那就是可以暂停函数执行,并返回出来。这样带来的好处是可以暂时执行其他的,然后再返回执行下面的代码。
当一个数字循环不用保存而只是使用一次的话,那么使用yield是非常省内存的方法。
- def func():
- for i in range(10000):
- yield '包子'+ str(i)
- v = func()
- for i in range(200):
- print(v.__next__())
send方法:
- def func():
- for i in range(10000): #3-10-17
- count = yield str(i)+'来了' #4-8-11-15-18
- print(f'{count}再吃包子{i}') #9-16
- v = func() #1
- print(v.__next__()) #2-5
- for i in range(2): #6-13
- v2 = v.send(i) #7-14-19
- print(v2) #12-20
这里比较绕哦,需要好好看。
send和next的相同点,不同点:
相同点:
都可以让商城器对应的yield向下执行一次
都可以获取到yield生成的值
不同点:
第一次获取yield值智能用next,不能用send(可以用send(None))
send可以给上一个yield传递值
yield from:
- def func():
- lis =[1,2,3,4,5]
- yield lis
- v = func()
- print(next(v))
- '''
- [1,2,3,4,5]
- '''
-
-
- def func():
- lis =[1,2,3,4,5]
- yield from lis
- v = func()
- print(next(v))
- print(next(v))
- print(next(v))
- print(next(v))
- '''
- 1
- 2
- 3
- 4
- 5
- '''
yield from的主要作用是将列表中的每一个元素返回一次。next多了还是会报错。没啥鸟用。了解即可。
生成器表达式:
- gen = (i**2 for i in range(10))
- for i2 in gen:
- print(i2)
- gen = (i for i in range(10) if i > 2) for i2 in gen: print(i2)
推导式
主要目的是为了方便将比较单一且有规律的做法使用简单的语句进行处理。
缺点是比较占用内存资源。
基本语句:
- lis = [ i for i in range(10)]
- print(lis)
这样就生成了一个0-9的列表。
推导式的分类:
循环推导式
#[变量(值) for 变量 in iterable]
筛选推导式
#[变量 for 变量 in iterable if 条件]
列表推导式:
- lis = [ i for i in range(10)] #基本格式
- lis = [ i if i > 3 else 8 for i in range(10)] #循环range,得出的结果依次判断,如果成立将添加,如果不成立就改成8
- lis = [i for i in range(10) if i > 3] #循环range,得出的结果依次判断,如果为True,那么就添加,如果为False,就不添加
- lis = [lambda x:x*i for i in range(10)] #得到的是循环10次的lambda表达式,如果lis[0](2),那么意思是巡行第1个lambda函数,将2传入到你,将得到18结果。
- def num():
- return [lambda x:i * x for i in range(4)]
- print([m(2) for m in num()])
字典推导式:
- lis1 = ['a','b','c']
- lis2 = ['1','2','3']
- dic = {lis1[i]:lis2[i] for i in range(len(lis1))}
- print(dic)
-
- lis1 = 'abc'
- lis2 = '123'
- dic = {lis1[i]:lis2[i] for i in range(len(lis1))}
- print(dic)
集合推导式:
- lis = [1,2,3,4,5,2,2,1,1,3,2,1]
- s = {i for i in lis}
- print(s)
Python——生成器&推导式的更多相关文章
- Python生成器/推导式/生成器表达式
一 生成器 生成器的本质就是迭代器 生成器的特点和迭代器一样,取值方式和迭代器一样(__next__(), send(): 给上一个yield传值) 生成器一般由生成器函数或者生成器表达式来创 ...
- python 生成器推导式与列表推导式的区别
生成器表达式现用现生成,列表推导式一次性生成静态数据 L = [2, 3, 5, 7] L2 = (x**2+1 for x in L) it = iter(L2) print(next(it)) L ...
- 12.Python略有小成(生成器,推导式,内置函数,闭包)
Python(生成器,推导式,内置函数,闭包) 一.生成器初始 生成器的本质就是迭代器,python社区中认为生成器与迭代器是一种 生成器与迭代器的唯一区别,生成器是我们自己用python代码构建成的 ...
- Python进阶(四)----生成器、列表推导式、生成器推导式、匿名函数和内置函数
Python进阶(四)----生成器.列表推导式.生成器推导式.匿名函数和内置函数 一丶生成器 本质: 就是迭代器 生成器产生的方式: 1.生成器函数
- 记录我的 python 学习历程-Day12 生成器/推导式/内置函数Ⅰ
一.生成器 初识生成器 生成器的本质就是迭代器,在python社区中,大多数时候都把迭代器和生成器是做同一个概念. 唯一的不同就是: 迭代器都是Python给你提供的已经写好的工具或者通过数据转化得来 ...
- Python函数04/生成器/推导式/内置函数
Python函数04/生成器/推导式/内置函数 目录 Python函数04/生成器/推导式/内置函数 内容大纲 1.生成器 2.推导式 3.内置函数(一) 4.今日总结 5.今日练习 内容大纲 1.生 ...
- Python之路-迭代器 生成器 推导式
迭代器 可迭代对象 遵守可迭代协议的就是可迭代对象,例如:字符串,list dic tuple set都是可迭代对象 或者说,能被for循环的都是可迭代对象 或者说,具有对象.__iter__方法的都 ...
- python 列表推导式,生成器推导式,集合推导式,字典推导式简介
1.列表推导式multiples = [i for i in range(30) if i % 2 is 0]names = [[],[]]multiples = [name for lst in n ...
- python的推导式 —— 列表推导式、集合和字典推导式
python的推导式是用于快速处理数据的方法. 主要有:列表推导式.集合推导式和字典推导式 import time import numpy as np 列表推导式: 1. 速度快 t1 = time ...
随机推荐
- Redis 启动 Please see the documentation included with the binary distributions for more details on the --maxheap flag.
启动redis的时候,出现 主要就是说 没有足够的可用的空间,可以使用maxheap减少redis堆的大小.或者重启系统对系统分页文件进行碎片整理. 解决方法就是在启动的时候加个 --maxheap ...
- copy函数是有返回值的!
用 copy() 函数来删除开头的元素: a = []int{1, 2, 3} a = a[:copy(a, a[1:])] // 删除开头1个元素 a = a[:copy(a, a[N:])] // ...
- 深度相机Astra Pro测试教程
最近在微信群内,很多群友在群友的推荐下,购买了Astra pro的深度相机,价格地道,物超所值!群友反馈积极,所以这里出一波简单的教程. 以下内容知识抛砖引玉,主要讲解windows下和Ubunt ...
- Qt编写数据可视化大屏界面电子看板系统
一.前言 目前大屏大数据可视化UI这块非常火,趁热也用Qt来实现一个,Qt这个一站式超大型GUI超市,没有什么他做不了的,大屏电子看板当然也不在话下,有了QSS和QPainter这两个无敌的工具组合, ...
- PMP 第11章错题总结
1.项目经理考虑每个人的观点并恢复秩序是合作/解决问题的技术2.评价团队有效性的指标包括---个人技能的改进.团队能力的改进.团队成员离职率的降低.团队凝聚力的加强3.管理质量包括所有质量保证活动,还 ...
- mockito的用法
well,说来惭愧,之前一直知道有这么个东西,但总是看不进去.刚好趁着这次迭代间隙有些闲暇,认真看了下,大概明白是怎么回事了. 首先,mock是个概念,这个词的本意就是“虚假的”.“模仿的”.在测试的 ...
- java自定义jar包让jemeter使用
背景:可能在做定义化的要求上,jmeter原有的jar包,已经不能满足我们,就需要自己写一个方法,以下就是写入的一个模拟post的请求,在jmeter中使用的案例 一:写代码 1.代码中的有两个包,原 ...
- ifcopenshell在VS2015下的编译
源起 今天使用 IfcOpenShell的IfcConvert ,因为是开源的所以就想自己编译下,编译过程中遇到不少问题,因此记录下来 什么是IfcOpenShell? IfcOpenShell是一个 ...
- 【视频开发】ONVIF、RTSP/RTP、FFMPEG的开发实录
ONVIF.RTSP/RTP.FFMPEG的开发实录 前言 本文从零基础一步步实现ONVIF协议.RTSP/RTP协议获取IPC实时视频流.FFMPEG解码.开发环境为WIN7 32位 + VS201 ...
- SimpleDataFormat 线程不安全解决
SimpleDataFormat 是我们常用的时间转换工具,我再spark中使用sdf对时间戳进行转换,发现转化出的时间有异常,原来sdf是线程不安全的, 改用joda time,错误消失,样例如下 ...