什么是生成器?

生成器的实质就是迭代器,我们能够从生成器中一个一的拿值

python中获取生成器的方式有三种:

1、通过生成器函数

2、通过生成器表达式

3、通过数据转换也可以获取生成器(某些对象执行一个方法就能返回一个生成器,这个现在用不到)

一、 生成器函数

 def gen():
代码块
yield 返回值 gen() #表示获取一个生成器,是一个内存地址,装的是代码,并不执行,用的时候才会执行

将return换成yield就是生成器函数了,上面就是生成器函数的格式。yield的作用是代码执行到这里就会停止,并且会返回一个值,所以代码能够分段执行,这就是生成器能逐个拿值的原因。

对于生成器函数,函数名+()并不表示函数执行,而是获取一个生成器对象。生成器装的是代码,只有在需要拿值的时候才会执行,这是生成器的惰性机制。

1、通过__next__访问生成器

 # def gen():
# print("娃哈哈")
# yield '爽歪歪'
# print("酸酸乳")
# yield 'AD钙奶'
# print('黄焖鸡米饭')
#
# ret = gen() #获取生成器对象,生成器装的是代码,要的时候运行一段
# print(ret) #<generator object gen at 0x0000000001E12F10> 生成器 generator
# print(ret.__next__()) #调用__next__才会执行,返回爽歪歪
# print(ret.__next__()) #调用__next__才会执行,返回Ad钙奶
#print(ret.__next__()) #StopIteration 迭代器,就找yield,找不到就会报错 往下运行,打印出了“黄焖鸡米饭”,但是找不到yield,所以报错

__next__()

2、通过send()访问生成器

send()可以取值的同时给上一个yield位置传值

 def func():
print("水饺")
a = yield "大馅水饺"
print("a=", a)
print("烧饼")
b = yield "武大郎烧饼"
print("b=", b)
print("老婆饼")
c = yield "只要老婆不要饼"
print("c =",c) g = func()
print("返回值是:",g.__next__())
print("返回值是:",g.send("面条"))
print("返回值是:",g.send("面条"))
#print("返回值是:",g.send("面条")) #c = 面条 报错 StopIteration #结果
水饺
返回值是: 大馅水饺
a= 面条
烧饼
返回值是: 武大郎烧饼
b= 面条
老婆饼
返回值是: 只要老婆不要饼

send()

send和__next__的区别:

  send()和__next__都可以让生成器向下走一段,但send可以给上一个yield位置传值,使用时不能在第一次,也不能给最后一个yield传值

二、推导式

1、列表推导式

语法:[ 结果  for循环  if判断 ]

 lst = ["中岛美雪","夏川美里","原由子","汪峰","田震","那英","周杰伦"]

 l = [name for name in lst if len(name) == 2  ] #这就是列表推导式
print(l)

2、字典推导式

语法:{ key:value  for循环  if判断 }

dic ={"张无忌":"赵敏","杨过":"小龙女","郭靖":"黄蓉"}
new_dic = {dic[k]: k for k in dic} #字典推导式
print(new_dic)
new = {v:k for k,v in dic.items()} #字典推导式
print(new)

字典推导式

3、集合推导式

语法:{ 结果 for循环  if判断 }

lst = [1,2,3,1,2,4]
se = {k for k in lst} #这是集合推导式
print(se) # {1,2,3,4}

集合推导式自带去重功能

5、没有元组推导式

6、生成器表达式

语法:( 结果 for循环  if判断 )

 names = [['Tom',"Billy","Jefferson","Abdrew","Wesley","Steven","Joe"],['Alice',"Jill","Ana","Wendy",'Jennifer','Sherry','Eva']]

 name_gen = (name for el in names for name in el if name.count("e")==2)
print(name_gen.__next__())
print(name_gen.__next__())
print(name_gen.__next__()) 结果
#Jefferson
#Wesley
#Steven

生成器表达式

生成器拿值方式:

1、用__next__和send

2、使用for循环

 gen = (i for i in range(1,100) if i % 3 == 0)
for num in gen:
print(num)

3、list(g),g是生成器

 gen = (i * i for i in range(100) if i % 3 == 0)
print(list(gen))

结果是一个列表

[0, 9, 36, 81, 144, 225, 324, 441, 576, 729, 900, 1089, 1296, 1521, 1764, 2025, 2304, 2601, 2916, 3249, 3600, 3969, 4356, 4761, 5184, 5625, 6084, 6561, 7056, 7569, 8100, 8649, 9216, 9801]

生成器的特性:

1、节省内存

2、惰性机制   (不到最后使用时不会拿值)

3、拿值只能往前,不能后退

惰性机制+只能往前拿值特性的组合考察(深坑):

def func():
print(111)
yield 222
g = func() # 生成器g
g1 = (i for i in g) # 生成器g1. 但是g1的数据来源于g
g2 = (i for i in g1) # 生成器g2. 来源g1
print(list(g)) # 获取g中的数据. 这时func()才会被执行. 打印111.获取到222. g完毕.
print(list(g1)) # 获取g1中的数据. g1的数据来源是g. 但是g已经取完了. g1 也就没有数据

print(list(g2)) # 和g1同理 #结果
111
222
[]
[]

**小知识  yield from**

yield ffrom 可以直接把可迭代对象中的每一个数据作为生成器的结果进行返回

def gen():
lst = ["花藤", "胡辣汤", "微星牌饼铛", "Mac牌锅铲"]
yield from lst g = gen() #获取生成器
for el in g:
print(el) 等价于:
def gen():
lst = ["花藤", "胡辣汤", "微星牌饼铛", "Mac牌锅铲"]
yield lst[0]
yield lst[0]
yield lst[0]
yield lst[0]
g = gen() #获取生成器
for el in g:
print(el)

yield from

**面试题**

1、

def gen():
lst = ["花藤", "胡辣汤", "微星牌饼铛", "Mac牌锅铲"]
lst2 = ["饼铛还是微星的好", "联想不能煮鸡蛋", "微星就可以", "还可以烙饼"]
yield from lst #yield from 会迭代返回列表中的元素,执行完lst才会执行lst2,所以不会有交替打印的效果
yield from lst2
g = gen()
for el in g:
print(el)
效果:
花藤
胡辣汤
微星牌饼铛
Mac牌锅铲
饼铛还是微星的好
联想不能煮鸡蛋
微星就可以
还可以烙饼

2、

def add(a,b):
return a + b
def test():
for r_i in range(4):
yield r_i
g = test()
for n in [2,10]:
g = (add(n,i) for i in g)
print(list(g))
#for循环第一次执行,n= 2时 g变为了 g = add(n,i) for i in (add(n,i) for i in test() 这时没取值,g也就不执行
# for第二次执行,n=10 此时 g= add(n,i) for i in (add(n,i) for i in test() 这时开始取值 ,g执行 结果:
[20, 21, 22, 23]

python记录_day12 生成器的更多相关文章

  1. python高级之生成器&迭代器

    python高级之生成器&迭代器 本机内容 概念梳理 容器 可迭代对象 迭代器 for循环内部实现 生成器 1.概念梳理 容器(container):多个元素组织在一起的数据结构 可迭代对象( ...

  2. 第三篇:python高级之生成器&迭代器

    python高级之生成器&迭代器   python高级之生成器&迭代器 本机内容 概念梳理 容器 可迭代对象 迭代器 for循环内部实现 生成器 1.概念梳理 容器(container ...

  3. 十二. Python基础(12)--生成器

    十二. Python基础(12)--生成器 1 ● 可迭代对象(iterable) An object capable of returning its members one at a time. ...

  4. Python三大器之生成器

    Python三大器之生成器 生成器初识 什么是生成器 生成器本身属于迭代器.继承了迭代器的特性,惰性求值,占用内存空间极小. 为什么要有生成器 我们想使用迭代器本身惰性求值的特点创建出一个可以容纳百万 ...

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

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

  6. 【python】迭代器&生成器

    源Link:http://www.cnblogs.com/huxi/archive/2011/07/01/2095931.html 迭代器 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素 ...

  7. python中的生成器函数是如何工作的?

    以下内容基于python3.4 1. python中的普通函数是怎么运行的? 当一个python函数在执行时,它会在相应的python栈帧上运行,栈帧表示程序运行时函数调用栈中的某一帧.想要获得某个函 ...

  8. 十三. Python基础(13)--生成器进阶

    十三. Python基础(13)--生成器进阶 1 ● send()方法 generator.send(value) Resumes the execution, and "sends&qu ...

  9. Python学习-39.Python中的生成器

    先回顾列表解释 lista = range(10) listb = [elem * elem for elem in lista] 那么listb就将会是0至9的二次方. 现在有这么一个需求,需要存储 ...

随机推荐

  1. CentOS7.2 问题收集 查看文件大小 查看端口

    1.在vmware中使用nat模式安装centos7.2,没有ifconfig命令? yum upgrade yum install net-tools 2.查看当前目录所有文件大小 [root@lo ...

  2. Java中sort实现降序排序

    利用Collections的reverseOrder方法: import java.util.Arrays; import java.util.Collections; public class Ma ...

  3. using Redis in .net core

    Using Redis Cache in .net Core Distributed Cache using Redis and ASP.NET Core ASP.NET Core Data Prot ...

  4. ComponentOne使用技巧——从Winform穿越到WPF

    概述 WPF 和 Winform 是两个单独的平台,但二者又都是基于 .NET 4.0 以上版本开发的,所以很多.NET开发人员就开始研究如何在WPF中使用Winform.微软已经架设了两个开发平台的 ...

  5. cmd中utf-8编码的问题

    有时候我们需要使用cmd显示某个utf-8编码的文本,这时候就需要设置cmd的代码页为65100. 也就是 chcp 65001 这条命令.这样设置可以临时生效. 如何要永久生效,需要在注册表中修改. ...

  6. PHP 常见的数据加密技术

    单项散列加密技术(不可逆的加密) 把任意长的输入字符串变化为固定长的输出串的一种函数 MD5 string md5 ( string $str [, bool $raw_output = false ...

  7. c# 通过反射输出成员变量以及成员变量的值

    /*** @Author rexzhao* 工具类 仅限于* public variable*/using System.Collections;using System.Collections.Ge ...

  8. 次短路——Dijkstra

    传送门 ——在LYC大佬的帮助下过了这道题 思路: LYC大佬的博客里已经讲得很清晰了,我只是提一下要点. 求次短路,主要考虑两个方面: ①在不重复走一条路的前提下,把最短路的其中一段替换为另一段. ...

  9. Bootstrap & Font Awesome 学习笔记

    学习网站:http://bootstrap.ninghao.net/index.html https://www.freecodecamp.cn http://www.runoob.com/boots ...

  10. header 格式

    headers = { 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,* ...