一.生成器

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

1)这里面函数体里是返回值return;如果将return换成yield就是生成器

 def func():
print("")
yield 222
ret = func()
print(ret)
#输出结果
<generator object func at 0x000001FDDCE5EEB8>

如果函数中包含了yield,那这个函数就是生成器了

所以:a;return直接返回结果,结束函数的调用

   b:返回结果,可以让函数分段执行

关于生成器的的小坑;

 def func():
i = 1
while i < 1000000:
yield "%s" % i
i += 1
print(func().__next__())#不是同一个生成器,开辟了一个新空间
print(func().__next__())#相当于一个新的生成器从第一步执行,相当于格式化了func()中的所有东西
print(func().__next__())
#1,1,1
为什么会不变呢,因为执行每一次print,都相当于重新拿了一个生成器,
然后从头开始找第一个yield;

生成器是不能进行赋值运算的;所以正确格式:上下两个程序少了一个func = func()

 def func():
i = 1
while i < 1000000:
yield "%s" % i
i += 1
6 func = func()
print(func.__next__())#不是同一个生成器
print(func.__next__())#相当于一个新的生成器从第一步执行
print(func.__next__())
#输出结果:
1,2,3

2)生成器的作用

 #代码一
def cloth1():
lst = []
for i in range(10000):
lst.append(i)
return lst
c1 = cloth1()
#代码二
def cloth():
for i in range(100000):
yield '衣服' + str(i+1)
c = cloth()
for i in range(10):
print(c.__next__())

这两段代码差别之处,就是代码一一下子就提取了10000个数,太耗内存;

代码二:是可以控制的,我要几个,你给我几个;惰性机制;

二.send和.next()的区别

1.还是上面的程序,你用._next_()的话,会直接一次性全拿出来值,会很占用内存,生成器的话,是可控的,一个一个

指下去,不会回去,下一次继续获取指针指向的值;

这里面send是怎么运行的,第一行._next_()是运行到红色范围的yield,然后print(g.send(1))是函数func

从a开始执行到下一个yield "22",然后把send的里面的1赋值给a;

代码展示:

 def func():
print("大碴粥")
a = yield ""
print(a)
print("狗不理")
b = yield ""
print(b)
print("大麻花")
c = yield "" g = func()
print(g.__next__())
print(g.send(1))
print(g.__next__())
#输出结果
大碴粥
11
1            #这是send里面的1赋值给了a
狗不理
22
None           #因为b是._next_()执行的,没用进行赋值,所以为None
大麻花
33

注意:第一个不能用send(),最后一个也不要传值;

三.列表推导式,生成器表达式以及其他推导式

1.列表推导式

平常代码:

 lst = []
for i in range(1,16):
lst.append(i)
print(lst)
#输出结果
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]

替换成列表推导式

lst = [i for i in range(1,16)]
print(lst)
#输出结果
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]

这里的lst直接相当于append进行的添加;

 lst = ["python%d" % i for i in range(1,16)]
print(lst)
#输出结果
['python1', 'python2', 'python3', 'python4', 'python5', 'python6', 'python7', 'python8', 'python9', 'python10', 'python11', 'python12', 'python13', 'python14', 'python15']
 判断列表中的有两个e的元素
names = [['Tom', 'Billy', 'Jefferson' , 'Andrew' , 'Wesley' , 'Steven' ,
'Joe'],['Alice', 'Jill' , 'Ana', 'Wendy', 'Jennifer', 'Sherry' , 'Eva']]
lst = [name for index in names for name in index if name.count("e") == 2]
print(lst)
#输出结果
['Jefferson', 'Wesley', 'Steven', 'Jennifer']

2.生成器推导式

a:生成器表达式和列表推导式基本一致,只是把[]替换成了()

gen = (i for i in range(10))

print(gen) #输出结果得到的是一串地址,你要用._next_()才能一步一步执行生成器;

生成器表达式和列表推导式两者的区别就是前者是惰性机制,要一个给一个,后者是一次性生成,比较耗内存;

b:生成器的惰性机制

上代码:

*************深坑请留意*************

 def func():
print(111)
yield 222
g = func() #生成器g
g1 = (i for i in g) #生成器g1,for循环只是让g变成了一个迭代器,而没有向它取值
g2 = (i for i in g1)   #生成器g2,跟g1相似,没有东西让他取值,就不运行
print(list(g)) #list内部有一个append,我跟你生成器要值了,你会运行你的函数
print(list(g1)) #而._next_()只是生成器要值后执行的语句,
print(list(g2))
#输出结果
111
[222]
[]
[]

这里面第一个print里面的list(g)相当于list.append()向g要值了,g才会去调用函数,就是你第四行的代码该运行

运行,但是就是不调用我的函数,你就只调用我的变量g,而不执行g;

而当运行第二个print里面的list(g1)时,执行g1=(i for i in g)时,g._next_()已经运行到最后一个yield了,

所以g1再迭代g,已经取不到值了.所以为空列表;

c:字典的生成器格式

ls1 = [1,2,3,4,5] ls2 = [5,6,7,8,9]

dic = {ls1[i]:ls2[i] for i in range(len(ls1))}

d:总结 推导式有:列表推导式,字典推导式,集合推导式,没有元组推导式

面试题:

 def add(a,b):
return a+b
def test():
for i in range(4):
yield i
g = test()
for n in [2,10]:
g = (add(n,i) for i in g)
'''
执行效果
n = 2
g = (add(n,i) for i in test())
n = 10
g = (add(n,i) for i in ((add(n,i) for i in test()))
这里一直没有取值操作,所以不会执行test()函数,而取n值的时候,是最后一步
才取的n值,你要带入了,我给你值,否则你就一直用我的变量带入吧;
'''
print(list(g))
#输出结果
[20, 21, 22, 23]

Python_011(生成器)的更多相关文章

  1. 介绍一款原创的四则运算算式生成器:CalculateIt2

    家里小朋友读一年级了,最近每天都有一些10以内的加减法口算练习,作为程序员爸爸,自然也是想办法能够偷懒,让电脑出题,给小朋友做些练习.于是,自己在业余时间开发了一个四则运算算式生成器,名为:Calcu ...

  2. 每天一个设计模式-7 生成器模式(Builder)

    每天一个设计模式-7 生成器模式(Builder) 一.实际问题 在讨论工厂方法模式的时候,提到了一个导出数据的应用框架,但是并没有涉及到导出数据的具体实现,这次通过生成器模式来简单实现导出成文本,X ...

  3. Objective-C 生成器模式 -- 简单实用和说明

    1.生成器模式的定义 将一个复杂的对象的构件与它的表示分离,使得同样的构建过程可以创建不同的表示 2.生成器模式的UML Builder :生成器接口,定义创建一个Product各个部件的操作 Con ...

  4. 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(25)-权限管理系统-系统管理员(附生成器)

    系列目录 这一节我们要着手建立系统管理员表,但发布之前,我先发布一个代码生成器给大家先用着. 这个生成器是为这个项目而生的,理论不能用于其他项目,而且写得比较潦草,但能用 下载地址 有兴趣要生成器源码 ...

  5. Python(四)装饰器、迭代器&生成器、re正则表达式、字符串格式化

    本章内容: 装饰器 迭代器 & 生成器 re 正则表达式 字符串格式化 装饰器 装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等.装饰器是解 ...

  6. ES6笔记(5)-- Generator生成器函数

    系列文章 -- ES6笔记系列 接触过Ajax请求的会遇到过异步调用的问题,为了保证调用顺序的正确性,一般我们会在回调函数中调用,也有用到一些新的解决方案如Promise相关的技术. 在异步编程中,还 ...

  7. C#/ASP.NET完善的DBHelper,配套Model生成器

    支持Oracle.MSSQL.MySQL.SQLite四种数据库,支持事务,支持对象关系映射:已在多个项目中实际使用. 没有语法糖,学习成本几乎为0,拿来即用. DBHelper类完整代码: usin ...

  8. Python 生成器与迭代器 yield 案例分析

    前几天刚开始看 Python ,后因为项目突然到来,导致Python的学习搁置了几天.然后今天看回Python 发现 Yield 这个忽然想不起是干嘛用的了(所以,好记性不如烂笔头.).然后只能 花点 ...

  9. Mockjs,模拟数据生成器

    (推荐使用)Mock.js是一款模拟数据生成器,旨在帮助前端攻城师独立于后端进行开发,帮助编写单元测试. 提供了以下模拟功能: 1. 根据数据模板生成模拟数据. 2. 模拟Ajax请求,生成并返回模拟 ...

随机推荐

  1. 测开之路一百零九:bootstrap列表

    bootstrap列表 引入bootstrap标签 原本的效果 水平显示 bootstrap列表 列表组合框 在组合框后面加备注 突出显示 a标签列表 <!DOCTYPE html>< ...

  2. 数模常用算法系列Matlab实现-----线性规划

    线性规划的 Matlab 标准形式 线性规划的目标函数可以是求最大值,也可以是求最小值,约束条件的不等号可以是小于号也可以是大于号.为了避免这种形式多样性带来的不便,Matlab 中规定线性 规划的标 ...

  3. Git016--Work

    GIT常用命令 git常用命令: //初始化git目录: $ git init //把当前目录变成git可以管理的仓库 //添加文件到暂存区 $ git add file //把文件添加到仓库 $ g ...

  4. ceph部署-常用命令

    常用命令:1.ceph healthceph -s 2.ceph osd treeceph osd lspoolsceph osd pool [poolname] rbd pg_numceph osd ...

  5. iptables防火墙常用命令

    iptables防火墙启动停止和基本操作 iptables是centos7之前常用的防火墙,在centos7上使用了firewall 防火墙基本操作: # 查询防火墙状态 service iptabl ...

  6. SA & SAM

    后缀数组SA \(sa[i]\)与\(rk[i]\) \(sa[i]\) 表示排名为 \(i\) 的后缀是哪一个(在原串中开头位置). \(rk[i]\)(或\(rank[i]\))表示开头位置是 \ ...

  7. Java 中的 T,E,K,V, 别傻傻分不清楚!

    作者:glmapper https://juejin.im/post/5d5789d26fb9a06ad0056bd9 前言 Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛 ...

  8. OSI模型——传输层

    OSI模型——传输层 运输层 运输层概述 运输层提供应用层端到端通信服务,通俗的讲,两个主机通讯,也就是应用层上的进程之间的通信,也就是转换为进程和进程之间的通信了,我们之前学到网络层,IP协议能将分 ...

  9. Flask 中请求钩子的理解和应用?

    请求钩子是通过装饰器的形式实现的,支持以下四种:1,before_first_request 在处理第一个请求前运行2,before_request:在每次请求前运行3,after_request:如 ...

  10. 在Centos7.6使用kubeadm部署k8s 1.14.3

    K8s不是一个软件,而是一堆软件的集合,由于这堆软件各自独立,因此可能k8s安装过程很容易出现问题 K8s部署有多种方式,本文使用kubeadm部署,从易操作性和可控性来说属于中等的方式 环境:cen ...