生成器

生成器
  生成器的本质就是迭代器
生成器的表现形式
  生成器函数
    生成器函数 —— 本质上就是我们自己写得函数
  生成器表达式
生成器函数:
  含有 yield 关键字的函数就是生成器函数
  特点:
    调用函数的之后函数不执行,返回一个生成器
    每次调用 next 方法的时候会取到一个值
    直到取完最后一个,在执行 next 会报错

从生成器中取值的几个方法
  1、next
  2、for
  3、数据类型的强制转换:占用内存 print(list(g))

生成器函数

我们先来看下普通函数

def generator():
print(1)
return 'a'
ret = generator()
print(ret)

接着来看生成器函数

#只要含有yield关键字的函数都是生成器函数
# yield 不能和 return 共用且需要写在函数内
def generator():
print(1)
yield 'a'
#生成器函数:在执行之后会得到一个生成器作为返回值
ret = generator() #此处的 ret 是一个生成器而不是值了
print(ret) #此处在同过原来的调用方法调用的是内存地址
print(ret.__next__()) #通过 .__next__() 来调用函数的输出内容

下面来看一个生成器函数的例子

#在取值时 会取到第一个 yield 时停止,然后等待下一次取值的动作开始,继续取值到下一个 yield
def generator():
print(1)
yield 'a'
print(2)
yield 'b'
print(3)
yield 'c'
g = generator() ret = g.__next__() #单独执行第一次时:1 a
print(ret)
ret = g.__next__() #即:可以控制执行的位置
print(ret)
ret = g.__next__()
print(ret) for i in g: #使用 for 循环也同样可以
print(i) #但 for 循环不可以控制执行位置

写一个函数 制造 200w 个娃哈哈

ef wahaha(*args):
for i in range(2000000):
yield "娃哈哈%s"%i
ret = wahaha(1000) #调用
#for i in ret:
# print(i) #调用前 50 个
count=0
for i in ret:
print(i)
count+=1
if count > 50:
break
print(ret.__next__()) #这里一起执行会接着 for 循环调用 ret ,返回第 51个

监听文件输入的例子

#当检查到文件中有输入含有 python 字符时就会在屏幕上打印
def tail(filename):
f = open(filename,encoding='utf-8') #文件句柄
while True:
line = f.readline()
if line.strip():
yield line.strip() ret = tail('D:/py/log/test.txt')
for i in ret:
if 'python' in i:
print('***',i)

生成器函数进阶

关键字 send 的使用

#send 获取下一个值的效果和 next 基本一致
#只是在获取下一个值的时候,给上一 yield 的位置传递一个数据
#使用 send 的注意事项
# 使用生成器取第一个值的时候 必须用 next 来取值
# 最后一个 yield 不能接受外部的值 def generator():
print(123)
content = yield 1
print('=====',content)
print(456)
yield 2 g = generator()
ret = g.__next__()
print('***',ret)
ret = g.send('hello') #向函数 content 的位置传值
print('***',ret)

获取移动平均值(每次输入一个值都会计算出一个平均值)

10 20 30 10
10 15 20 17.5
avg = sum/count

def average():
sum = 0
count = 0
avg = 0
while True:
num = yield avg
sum +=num
count += 1
avg = sum/count avg = average()
avgs = avg.__next__()
avgs = avg.send(10)
avgs = avg.send(30)
avgs = avg.send(60)
avgs = avg.send(60)
print(avgs)

预激生成器的装饰器
获取移动平均值进阶与装饰器的使用

#装饰器的作用就是在用户使用时,少写一句 ret = g.__next__() 方便操作
def init(func):
def inner(*args,**kwargs):
ret = func(*args,**kwargs)
ret.__next__()
return ret
return inner @init
def average():
sum =0
count = 0
avg = 0
while True:
num = yield avg
sum += num
count += 1
avg=sum/count avg = average()
ret = avg.send(10)
ret = avg.send(20)
ret = avg.send(60)
print(ret)
ret = avg.send(20)
ret = avg.send(20)
print(ret)

from 关键字的使用

#先来看一个 for 循环的例子,取出字符串中所有的单个字符
def generator():
a = 'abcde'
b = ''
for i in a:
yield i
for i in b:
yield i
g = generator()
for i in g:
print(i) #使用 from 关键字取出
def generator():
a = 'abcde'
b = ''
yield from a
yield from b g = generator()
for i in g:
print(i)

生成器的表达式

来看简单的生成器表达式的例子

g = (i for i in range(10))
ret = g.__next__()
print(ret) for i in g:
print(i) 老母鸡=('鸡蛋%s'%i for i in range(10)) #生成器表达式
print(老母鸡)
for 蛋 in 老母鸡:
print(蛋) g = (i*i for i in range(10))
g.__next__()
for i in g:
print(i) '''
生成器表达式与列表推导式的区别
1、括号不一样(列表为:[],生成器为:())
2、返回的值不一样 === 几乎不占用内存
'''

各种推导式

包括:生成器 列表 字典 集合

生成器表达式与列表表达式语法一样 换个括号基本就 ok

作用:遍历操作、筛选操作
[每一个元素或者是和元素相关的操作 for 元素 in 可迭代数据类型] —— 遍历之后挨个处理
[满足条件的元素相关的操作 for 元素 in 可迭代数据类型 if 元素相关的条件] —— 筛选功能

列表推导式例子

# 30以内所有能被3整除的数
ret = [i for i in range(30) if i%3 == 0]
print(ret) # 30以内所有能被3整除的数的平方
g = [i*i for i in range(30) if i%3 ==0]
print(g) ''' # 找到嵌套列表中名字含有两个‘e’的所有名字
names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'],
['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']]
e = [name for lis in names for name in lis if name.count('e') == 2]
print(e)

字典推导式例子

#例一:将一个字典的key和value对调 效果:{10:'a' , 34:'b'}
mcase = {'a': 10, 'b': 34}
mcase_frequency = {mcase[k]: k for k in mcase}
print(mcase_frequency) # 例二:合并大小写对应的value值,将k统一成小写,效果:{'a':10+7,'b':34,'z':3}
mcase = {'a': 10, 'b': 34, 'A': 7, 'Z': 3}
mcase_frequency = {k.lower(): mcase.get(k.lower(), 0) + mcase.get(k.upper(), 0) for k in mcase}
print(mcase_frequency)

集合推导式

#集合推导式,自带结果去重功能
squared = {x**2 for x in [1, -1, 2]}
print(squared)

day 14 - 1 生成器的更多相关文章

  1. IntelliJ IDEA 14 注册码生成器

    IntelliJ IDEA 14 注册码生成器 文件为Java代码 自己编译运行里面的程序输入名称然后就生成注册码了工具:http://yun.baidu.com/s/1cZKsA部分工具生成的注册码 ...

  2. day 14 - 2 生成器练习

    相关练习 1.处理文件,用户指定要查找的文件和内容,将文件中包含要查找内容的每一行都输出到屏幕 #比较 low 的方法 def check_file(filename,aim): with open( ...

  3. Python基础(生成器)

    二.生成器(可以看做是一种数据类型) 描述: 通过列表生成式,我们可以直接创建一个列表.但是,受到内存限制,列表容量肯定是有限的.而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我 ...

  4. Python2.4-原理之函数

    此节来自于<Python学习手册第四版>第四部分 一.函数基础 函数的作用在每个编程语言中都是大同小异的,,这个表是函数的相关语句和表达式. 1.编写函数,a.def是可执行代码,pyth ...

  5. WinForm GDI+自定义控件总结(一)

    前言 由于项目的原因好久没写博客了,也正是项目的原因开始系统的学习WinForm,从而接触到自定义控件的开发.自定义控件的开发有一定的难度,对开发者要求比较高,需要了解Windows运行的机制,熟悉w ...

  6. (转)用AGG实现高质量图形输出(三)

    转自 :http://www.cnblogs.com/CoolJie/archive/2011/04/27/2030260.html 线段生成器(Span Generator) 我们前面举的例子使用的 ...

  7. python核心编程第二版笔记

    python核心编程第二版笔记由网友提供:open168 python核心编程--笔记(很详细,建议收藏) 解释器options:1.1 –d   提供调试输出1.2 –O   生成优化的字节码(生成 ...

  8. python核心编程--笔记

    python核心编程--笔记 的解释器options: 1.1 –d   提供调试输出 1.2 –O   生成优化的字节码(生成.pyo文件) 1.3 –S   不导入site模块以在启动时查找pyt ...

  9. Vegas Pro 15软件界面对比

    大家都知道Vegas是一款专业的视频制作软件,而新版的VEGAS Pro 15更是专业性十足.好了,废话不多说,接下来小编就带大家具体的看一下Vegas 15界面都有哪些更新吧! 一.软件图标 图1: ...

随机推荐

  1. 10分钟,AppCan帮你搞定跨平台开发APP问题!

    跨平台开发APP时,开发者总会遇到一些问题,如打包失败等等,尤其对于iOS来说,由于它的限制性会导致一些状况发生(如证书上传问题等),小编总结了几个AppCan在线IOS打包失败常见的情况及排查技巧, ...

  2. STM32F103/429串口IAP+Ymodem升级

    起因: 串口IAP升级在正点原子的例程中有讲解,正点原子的方法是:在RAM中开辟一个120K的数据空间,用来存放bin文件,bin文件通过串口一次性发送到单片机,然后再实现程序的跳转.但是这种方法在实 ...

  3. 导出pdf功能

    本程序下载地址: PDF是我们极其常用的文件格式,但对如何生成PDF,个人一直觉得很神秘,其实利用一些公开的PDF库,我们就可以直接生成PDF文件,而不用关注PDF文件的内部细节.我知道的PDF库有如 ...

  4. 在 CentOS 7 中安装 MySQL 8

    准备 本文环境信息: 软件 版本 CentOS CentOS 7.4 MySQL 8.0.x 安装前先更新系统所有包 sudo yum update 安装 1. 添加 Yum 包 wget https ...

  5. 06 Django REST Framework 版本控制

    01-版本控制 对接口进行版本控制只是一种杀死已部署客户端的“礼貌”方式. - 罗伊菲尔丁. 1. API版本控制允许您更改不同客户端之间的行为.REST框架提供了许多不同的版本控制方案. 2. 版本 ...

  6. kettle集群(转换)

    1.定义子服务器 新建子服务器中有一个必须为主服务器 新建集群 在需求集群运行的步骤中右键集群进行使用

  7. Bugku 分析 中国菜刀

    解压之后得到了一个流量包,只有不到10KB,美滋滋 先抓重点,过滤出http,只有6条数据记录,3条post,3条response,3条post都是一样的 随便打开一条pos 是一个assert断言, ...

  8. Vue组件以及组件之间的通信

    一.组件的注册 1. 全局组件注册 1. 注册基本语法Vue.component Vue.component("my_header", { template: `<div&g ...

  9. luogu P1744 采购特价商品

    实话说我本来想找SPFA的题,结果我硬生生的把这道题做成了Floyd 先来看题,我们会发现如果把他所给的变量都输入,那么会发现用Floyd的解法,输入占了main函数的一半长度... 题目分为两步走: ...

  10. P1137 旅行计划

    /*拓扑排序去寻找点的拓扑序 便于DP,那么怎么去找 首先邻接表存边,然后dfs搜寻每一个点 最后进行拓扑排序,找到拓扑序*/ #include<bits/stdc++.h> ; ; us ...