1、生成器

 生成器的本质就是迭代器.

 1.1  获取生成器

  1:  生成器函数

   函数中出现 "yield" 的函数就是一个生成器函数, 再次执行函数时就不是运行函数而是获取生成器.

  2: 生成器推导式

   ( i for i in range( 20) )  ----> 不是元组生成式, 而是生成器推导式, 它获取的是一个生成器.

        gen = ( i for i in range( 20) ), gen就是一个生成器

 1.2  生成器取值方式:  

    1,  通过__next__()取值.     2 , 通过send(" ")取值并传值.

 def func():
print("黄焖鸡") #
yield "黄焖鸡yield" #
print("烧鸭") #
yield "烧鸭yield" #
print("蒸鹿茸") #
yield "蒸鹿茸yield" #
print("蒸熊掌") gen = func() # 函数中出现"yield" 时,表示该函数为生成器,获取生成器.
print(gen) # 结果是一个生成器地址. <generator object func at 0x000002798C873C78>
gen.__next__() # 取到函数体中yield的那行就停止(第1,2行),并将yield后面的内容返回给调用者
print(gen.__next__()) # 再次调用就从上次停止的yield下行(第3行)开始运行,截止到第四行.
print(gen.__next__())
print(gen.__next__()) # 如果yield内容结束,还继续调用,则报错,但是print("蒸熊掌")还是会继续执行的

生成器__next__()取值

 1.2  生成器本质就是迭代器, 如何满足迭代器的三个特点呢?

 def buy():
lst = []
for i in range(1000):
lst.append("帽子%s" %(i)) # 把多有的帽子放在内存的列表里,占得内存大
return lst
print(buy()) def buy_gen():
for i in range(1000):
yield "帽子%s" %(i) # 不是一次性全部把帽子0.......帽子999放在内存,
# 而是通过__next__()一个一个取,比较省内存,但是不能往前执行,
# 满足迭代器的三个特点
gen = buy_gen()
print(gen.__next__())
print(gen.__next__())
print(gen.__next__())
print(gen.__next__())

如何满足迭代器的三个特点

 def baocaiming():
print("蒸鹿茸")
a = yield "蒸鹿茸yield"
print("a=",a)
print("蒸熊掌")
b = yield "蒸熊掌yield"
print("b=", b)
print("烧花鸭")
c = yield "烧花鸭yield"
print("c=", c)
print("烧子鹅") gen = baocaiming()
print(gen.__next__()) # 第一次只能用__next__()取值
print(gen.send("a++")) # 从上一次停止的yield开始执行,并将"a++"传给上次yield之前的变量a, a == "a++"
print(gen.send("b++"))
print(gen.send("c++")) # 函数里没有yield了,还继续调用,则报错,但是print("蒸熊掌")还是会继续执行的

生成器send()取值

  send()取值方式机理?

2、各种推导式

 2.1  列表推导式

  [ 结果  for循环  if条件 ]

 # 1到20 所有奇数的平方
lst = [i**2 for i in range(20) if i % 2 == 1]
print(lst) # 将 a = [3,6,9] 转化成----> [(1,2,3),[4,5,6],[7,8,9]]
print([(ele-2,ele-1,ele-0) for ele in a]) # 查找名字里面有两个"e"的名字
names = [
['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'],
['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva'],
]
print([r for i in names for r in i if r.count("e") == 2])

列表推导式

 2.2  字典、集合推导式

  {结果  for循环  if条件}

 dic = {"张无忌":"赵敏", "杨过":"小龙女", "郭靖":"黄蓉"}   # 将键,值换成值,键
new_dic = {v:k for k,v in dic.items()}
print(new_dic) # lst = [11, 22, 33] # => {0:11, 1:22, 2:33}
lst = [11, 22, 33]
dic = {i:lst[i] for i in range(len(lst))}
print(dic)

字典推导式

 2.3  生成器推导式

  (结果  for循环  if条件)    注意: 不是元组推导式, 元组是没有推导式!

  生成器表达式和列表推导式有什么不同?

    1: 列表推导式是一次性加载完, 耗内存; 生成器表达式几乎不占内存, 只有取值时候才分配和使用内存;

    2: 列表推导式得到的是一个列表, 生成器表达式得到的是一个生成器.

 2.4  生成器的惰性机制?

 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, g2数据来源于g1
# --------------------------------截至到此,还没有生成器拿过值
# 惰性机制----只要不访问就永远拿不到值
print(list(g)) # ----> [222] 获取到g中的数据,此时才执行func()函数,将222返回给g.
print(list(g1)) # ----> [] list(g)已经将生成器g中的数据拿完了,所以g1拿不到数据,只能为[]
print(list(g2)) # ----> [] g2和g1一样,拿不到值. # list() 的机理? (list()包含了for循环的机理)
# list() ----> 包含了for循环 ----> 通过__iter__()将可迭代对象转化成了
# 迭代器 ----> 通过__next__()从迭代器里取值 ----> 将拿到的值添加进列表里

生成器惰性机制

 2.5  yield from

   把可迭代对象中的每一个元素作为生成器的结果返回.

 def gen():
lst = ["⿇花藤", "胡辣汤", "微星牌饼铛", "Mac牌锅铲"]
lst2 = ["饼铛还是微星的好", "联想不能煮鸡蛋", "微星就可以", "还可以烙饼"]
yield from lst # 把 lst中的每一个元素作为生成器的结果返回给调用者.
yield from lst2 # 两个yield不会产生交替的效果. g = gen()
for el in g:
print(el)

yield from

python摸爬滚打之day12----生成器, 各种生成式的更多相关文章

  1. python基础学习Day12 生成器、列表推导式、字典的表达式、字典键值对的互换、集合推导式

    一.生成器 1.1 生成器:就是(python)自己用代码写的迭代器,生成器的本质就是迭代器. 1.2 生成器函数 def func1(x): x += print() yield x print() ...

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

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

  3. python基础语法9 生成器,面向对象编程思想,三元表达式,列表生成式,生成器表达式(生成式),匿名函数,内置函数

    生成器 1.什么是生成器? 生成的工具. 生成器是一个 "自定义" 的迭代器, 本质上是一个迭代器. 2.如何实现生成器 但凡在函数内部定义了的yield, 调用函数时,函数体代码 ...

  4. Python迭代器生成器与生成式

    Python迭代器生成器与生成式 什么是迭代 迭代是重复反馈过程的活动,其目的通常是为了逼近所需目标或结果.每一次对过程的重复称为一次"迭代",而每一次迭代得到的结果会作为下一次迭 ...

  5. python之迭代器与生成器

    python之迭代器与生成器 可迭代 假如现在有一个列表,有一个int类型的12345.我们循环输出. list=[1,2,3,4,5] for i in list: print(i) for i i ...

  6. day12——生成器、推导式、简单内置函数

    day12 生成器 迭代器:python中内置的一种节省空间的工具 生成器的本质就是一个迭代器 迭代器和生成器的区别:一个是pyhton自带的,一个是程序员自己写的 写一个生成器 基于函数 在函数中将 ...

  7. Python之路,Day12 - 那就做个堡垒机吧

    Python之路,Day12 - 那就做个堡垒机吧   本节内容 项目实战:运维堡垒机开发 前景介绍 到目前为止,很多公司对堡垒机依然不太感冒,其实是没有充分认识到堡垒机在IT管理中的重要作用的,很多 ...

  8. python基础—迭代器、生成器

    python基础-迭代器.生成器 1 迭代器定义 迭代的意思是重复做一些事很多次,就像在循环中做的那样. 只要该对象可以实现__iter__方法,就可以进行迭代. 迭代对象调用__iter__方法会返 ...

  9. Python之迭代器,生成器

    迭代器 1.什么是可迭代对象 字符串.列表.元组.字典.集合都可以被for循环,说明他们都是可迭代的. from collections import Iterable l = [1,2,3,4] t ...

随机推荐

  1. Geany的"跳转到标记定义“功能如何使用

    Geany是个比较轻量级的代码编辑器,在一些不怎么需要编辑的代码上,我比较常用它来浏览代码.不过它的 跳转到标记定义(Go to tag definition) 功能有点奇怪,一开始死活不知道怎么用, ...

  2. git配置用户名邮箱,全局配置/单仓库配置

    在项目根目录下进行单仓库配置(作用域只在本仓库下): git config user.name "gitlab's Name" git config user.email &quo ...

  3. Ubuntu 设置NAT共享网络(命令行方法)

    本文介绍如何使用iptables来实现NAT转发,事实上就是将一台机器作为网关(gateway)来使用.我们假设充当网关的机器至少有网卡eth0和eth1,使用eth0表示连接到外网的网卡,使用eth ...

  4. 详解 Redis 应用场景及应用实例

    redis(二)高级用法 详解 Redis 应用场景及应用实例 Redis 它是什么?它用来做什么?它的优势与短板如何? 告诉你Redis是一个牛逼货

  5. POJ 1904 King&#39;s Quest(强连通)

    Language: Default King's Quest Time Limit: 15000MS   Memory Limit: 65536K Total Submissions: 7635   ...

  6. metroui

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  7. ehcache缓存配置与参数说明

    <diskStore path="java.io.tmpdir" /> <defaultCache eternal="false" maxEl ...

  8. 【CF587F】Duff is Mad AC自动机+分块

    [CF587F]Duff is Mad 题意:给出n个串$s_1,s_2..s_n$,有q组询问,每次给出l,r,k,问你编号在[l,r]中的所有串在$s_k$中出现了多少次. $\sum|s_i|, ...

  9. Cannot change version of project facet Dynamic Web Module to 3.0 异常问题处理

    如何解决Tomcat服务器在初始化应用的时候的以下异常问题 1,Cannot change version of project facet Dynamic Web Module to 3.0 2,O ...

  10. Flask web开发之路一

    之前学过一段时间的flask,感觉还是挺好用的,自己的专利挖掘项目也想这个web框架来搭建,于是重新开始基础学习 环境:win10,python3.6,pycharm2017,虚拟环境virtuale ...