生成器

生成器的本质就是迭代器,那么还为什么有生成器呢,两者唯一的不同就是迭代器都是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的列表。

推导式的分类:

  1. 循环推导式

    #[变量(值) for 变量 in iterable]

  2. 筛选推导式

    #[变量 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——生成器&推导式的更多相关文章

  1. Python生成器/推导式/生成器表达式

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

  2. python 生成器推导式与列表推导式的区别

    生成器表达式现用现生成,列表推导式一次性生成静态数据 L = [2, 3, 5, 7] L2 = (x**2+1 for x in L) it = iter(L2) print(next(it)) L ...

  3. 12.Python略有小成(生成器,推导式,内置函数,闭包)

    Python(生成器,推导式,内置函数,闭包) 一.生成器初始 生成器的本质就是迭代器,python社区中认为生成器与迭代器是一种 生成器与迭代器的唯一区别,生成器是我们自己用python代码构建成的 ...

  4. Python进阶(四)----生成器、列表推导式、生成器推导式、匿名函数和内置函数

    Python进阶(四)----生成器.列表推导式.生成器推导式.匿名函数和内置函数 一丶生成器 本质: ​ 就是迭代器 生成器产生的方式: ​ 1.生成器函数

  5. 记录我的 python 学习历程-Day12 生成器/推导式/内置函数Ⅰ

    一.生成器 初识生成器 生成器的本质就是迭代器,在python社区中,大多数时候都把迭代器和生成器是做同一个概念. 唯一的不同就是: 迭代器都是Python给你提供的已经写好的工具或者通过数据转化得来 ...

  6. Python函数04/生成器/推导式/内置函数

    Python函数04/生成器/推导式/内置函数 目录 Python函数04/生成器/推导式/内置函数 内容大纲 1.生成器 2.推导式 3.内置函数(一) 4.今日总结 5.今日练习 内容大纲 1.生 ...

  7. Python之路-迭代器 生成器 推导式

    迭代器 可迭代对象 遵守可迭代协议的就是可迭代对象,例如:字符串,list dic tuple set都是可迭代对象 或者说,能被for循环的都是可迭代对象 或者说,具有对象.__iter__方法的都 ...

  8. python 列表推导式,生成器推导式,集合推导式,字典推导式简介

    1.列表推导式multiples = [i for i in range(30) if i % 2 is 0]names = [[],[]]multiples = [name for lst in n ...

  9. python的推导式 —— 列表推导式、集合和字典推导式

    python的推导式是用于快速处理数据的方法. 主要有:列表推导式.集合推导式和字典推导式 import time import numpy as np 列表推导式: 1. 速度快 t1 = time ...

随机推荐

  1. c# Mono.Cecil IL方式 读MethodBody

    using Kufen.Common.Definitions; using Mono.Cecil; using System; using System.Collections.Generic; us ...

  2. Qt编写项目作品大全(自定义控件+输入法+大屏电子看板+视频监控+楼宇对讲+气体安全等)

    一.自定义控件大全 (一).控件介绍 超过160个精美控件,涵盖了各种仪表盘.进度条.进度球.指南针.曲线图.标尺.温度计.导航条.导航栏,flatui.高亮按钮.滑动选择器.农历等.远超qwt集成的 ...

  3. JDK8:Lambda根据 单个字段、多个字段,分组求和

    使用lambda表达式分别 根据 单个字段.多个字段,分组求和 示意图: 1.根据 单个字段,分组求和:根据2019这个字段,计算一个list集合里,同属于2019的某个字段累加和 2.根据 多个字段 ...

  4. IntelliJ IDEA Error:(24, 35) java: 常量字符串过长

    在转换一个JSON转Java对象是 idea 编译不通过  提示:Error:(24, 35) java: 常量字符串过长 File -> Settings -> Build,Execut ...

  5. phpspreadsheet 中文文档(一) 访问单元格

    2019年10月11日11:45:09 访问单元格 访问电子表格中的单元格应该非常简单.本主题列出了一些访问单元的选项. 通过坐标设置单元格值 可以使用工作表的setCellValue()方法来按坐标 ...

  6. vue使用px2rem

    配置 flexible 安装 lib-flexible 在命令行中运行如下安装: 1 npm i lib-flexible --save 引入 lib-flexible 在项目入口文件 main.js ...

  7. 【NPDP笔记】第七章 产品生命周期管理

      7.1产品生命周期管理 7.1.1 产品生命周期简介 阶段 开发 引入 Introduction 成长 Growth 成熟 Maturity 衰退 Decline 生命周期变短 客户有更多需求 竞 ...

  8. Eclipse 单个tomcat多个项目部署原理(tomcat配置的环境变量catalina.home和catalina.base)

    一:概念 catalina.home(安装目录):指向公用信息的位置,就是bin和lib的父目录. catalina.base(工作目录):指向每个Tomcat目录私有信息的位置,就是conf.log ...

  9. initramfs文件系统制作

    源码下载:https://busybox.net/downloads/ 源码版本:busybox-1.30.0.tar.bz2 [ 源码编译步骤 ] make menuconfig ARCH= COM ...

  10. Mybaties的简单使用(全当做复习了)

    在使用mybaties的时候,最容易忘掉的是他的动态SQL,不过网上有关这方面的文章很多. 在动态SQl中最常见的几种SQL的语法就是: if choose (when, otherwise) tri ...