python 生成器generator
关于生成器,主要有以下几个 关键点的内容
一、什么是generator ,为什么要有generator?
二、两种创建生成器方式
三、yield关键字
四、generator 两个调用方法 next() 和send()
一、什么是generator ,为什么要有generator?
generator 是一种方式 ,是一种借助于循环,然后不断产生值的一种机制。(我是能理解机制这种描述,想了个例子来说明这个例子感觉又不对。)
那么为什么需要generator呢?一、 当你需要获取大量值的时候,我们可以将值存在列表里面,然后循环,读出没一个值。这没毛病。
但是你知道数组这种数据结构,他是将所有的值都紧挨着放在一块的,
当我们将这很多值,都放在内存中,主存是需要申请很大一块空间,
进行存放的,而我们的操作系统还要执行其他的任务,也要用到主存。这样将会导致操作RAM大量被占用,其他任何执行不了,或者干脆,其他任务执行完了,把地方让出来给你,你再去执行。以上的描述大家能感觉出来效率是非常低的。
可是我们有的时候就是需要啊,需要获取这种大量数据。(什么情况下,其实我写了几个项目现在也没有用到过generator,不过知道python的协程就是用生成器实现的。)而生成器他通过循环,计算出的数据,也就是说每循环一次就产生一次数据。这样是不需要向上面一样大量占用内存空间的,至于你说你需要计算啊(对于cpu来你这点代码量,简直就是连9牛一毛都称不上,这大兄弟可是每秒钟,能计算几十亿次)。
二、两种生成器的创建方式
1 、(x for x in range) ,就是将列表推到值外边的列表换成了元组。
2、函数中包含yield 关键字
def f1(n): yield n obj = f1(1) print(obj) 返回值是这个东西 <generator object f1 at 0x0000000001F1FFC0> 是一个生成器对象
三 、 yield 关键字
我们知道一个函数包含一个yield关键字 ,返回的就是一个generator ,那么这个yield关字是怎么运作的,他都有那些特性
请看如下代码,这个就是一个生产这消费者模型
def consumer(): r = 'ok' while True: n1 = yield r while not n1: print('如果走了这里,说明,下一次调用之前先将上一次的NONE给赋值了') print('consumer consume %s'%(n1)) r = '我不想吃包子,我想吃pizza' def producer(c): data =c.send(None) print(data ,'到底一次yield有没有返回值') n=0 while n <5: n+=1 print('生产者生产了%s'%n) data_2=c.send(n) print('消费者其实想的是%s'%(data_2)) obj =consumer() producer(obj)
我建议,如果你看了我的博客,可以复制一下代码去执行一下。就能总结出来yield关键字有如下特性:
1、yiled 关键字类似于return ,就是函数执行到这里后,就不在向下执行,然后返还一个返回值。但是(一提但是就要仔细看啊)当 执行到yield 关键字时,整个函数一个运行状态是还保存在内存,当下次再调用这个生成器时,会从yield开始,在向下执行,
而不是从函数开头从新执行一遍。然后循环到了yield 在卡住,等待下次再调用
2、yield 可以被传值,不过必须要通过send()方法
四、generator 两个调用方法 next() 和send()
我们一直在强调,generator 是借助于循环,不断产生新的值,所以就能理解 ,一般一个生成器都应该是一个循环中被调用,产生一个新的值。
所以
def f1(n): while True: n +=1 yield n obj = f1(1) for i in obj: print(i) 你可尝试一下,无限循环的感觉。
当然一般情况下,不会是无限循环 ,肯定是有一个终止条件的。
如下
def f1(n): while n<5: n +=1 yield n obj = f1(1) j =0 while j<5: j+=1 try: print(next(obj)) except StopIteration as e: print('别调用了,最多能计算这么多') 当生成器已经计算结束后,你在去调用会报错的 ,如果是直接用for 调用是不会报错的。其实for 结构里面就类似上面的代码,只是当循环完generator后,抓去了对应的异常。结束循环。
最后则是send 方法 , 而send 方法,他有两个作用,第一个是可以调用这个generator计算,第二个就是给yield赋值,在将上面的代码赋值一下
def consumer(): r = 'ok' while True: n1 = yield r while not n1: print('如果走了这里,说明,下一次调用之前先将上一次的NONE给赋值了') print('consumer consume %s'%(n1)) r = '我不想吃包子,我想吃pizza' def producer(c): data =c.send(None) print(data ,'到底一次yield有没有返回值') n=0 while n <5: n+=1 print('生产者生产了%s'%n) data_2=c.send(n) print('消费者其实想的是%s'%(data_2)) obj =consumer() producer(obj)
关于send 方法有一个特性,就是在第一次启动生成器的时候,要传一个None,或者先用next调用一下。原因是,当第一次走到yield的时候,yield 直接将会返回值返回,然后这次执行就停掉了,并没有发生赋值的操作,所以你传进来一个值,是没有效果的所以python的源码里面就做了处理。而第二次在在用send唤醒generaot ,send方法在传一个值,在将这个值传给yield 关键字。然后yield在赋值,然后整个函数再向下运行。
还有个小点,就是在函数调用,生成一个generatro对象时,函数是什么执行的,只有在被调用,或者被for循环时,才开始执行。
python 生成器generator的更多相关文章
- Python 生成器 (generator) & 迭代器 (iterator)
python 生成器 & 迭代器 生成器 (generator) 列表生成式 列表生成式用来生成一个列表,虽然写的是表达式,但是储存的是计算出来的结果,因此生成的列表受到内存大小的限制 示例: ...
- 【python之路29】python生成器generator与迭代器
一.python生成器 python生成器原理: 只要函数中存在yield,则函数就变为生成器函数 #!usr/bin/env python # -*- coding:utf-8 -*- def xr ...
- python生成器(generator)、迭代器(iterator)、可迭代对象(iterable)区别
三者联系 迭代器(iterator)是一个更抽象的概念,任何对象,如果它的类有next方法(next python3)和__iter__方法返回自己本身,即为迭代器 通常生成器是通过调用一个或多个yi ...
- python 生成器 generator
一.生成器定义 通过列表生成表达式,我们可以直接创建一个列表.但是,受到内存限制,列表容量肯定是有限的.所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢? ...
- Python 生成器 Generator 和迭代器 Iterator
#最近一周刚开始接触python,基本的语法,和使用特性和Java差别还是蛮大的. 今天接触到Python的迭代器和生成器有点不是很明白,所以搜索了先关资料整理了一些自己的理解和心得 简述(Profi ...
- python 生成器(generator)的生成方式
generator包括生成器和带yield的generator函数. 写了一个生成杨辉三角的小例子: # -*- coding:utf-8 -*- def triangles(): l = [1] w ...
- 【转】 Python生成器generator之next和send运行流程
原文链接:https://blog.csdn.net/pfm685757/article/details/49924099 对于普通的生成器,第一个next调用,相当于启动生成器,会从生成器函数的第一 ...
- Python进阶内容(四)--- 迭代器(Iterator)与生成器(Generator)
迭代器 我们已经知道,可以直接作用于for循环的数据类型有以下几种: 一类是集合数据类型,如list.tuple.dict.set.str等: 一类是generator,包括生成器和带yield的ge ...
- Python学习笔记 - 生成器generator
#!/usr/bin/env python3 # -*- coding: utf-8 -*- # generator 生成器 L = [x * x for x in range(10)] print( ...
随机推荐
- 把 Nginx 创建为 Windows 的一个服务
译序:Nginx 不是为 Windows 而写.Nginx 是用在软件的工作环境中的.但软件开发环境一般都是 Windows,有时调试的需要也要装 Nginx,但 Nginx 并没给 Windows ...
- [再寄小读者之数学篇](2014-06-22 求极限 [中国科学技术大学2011年高等数学B考研试题])
设数列 $\sed{x_n}$ 满足 $0<x_1<\pi$, $x_{n+1}=\sin x_n\ (n=1,2,\cdots)$. (1) 证明 $\dps{\vlm{n}x_n}$ ...
- wc 命令详解
1.wc 命令作用 统计文件里面有多少单词,多少行,多少字符. 2.wc 语法 wc [-lwm] 选项与参数:-l :仅列出行:-w :仅列出多少字(英文单字):-m :多少字符: 3.例子 使用w ...
- Python3:字符串的大小写和镜像字符串(swapcase()函数,chr(),ord(),translate()函数)
题目: 请编程实现字符串的转换:1. 将"adsdsfdndsdsdfsfdsdASDSDEDSFE18754"字符串大写变小写,小写变大写:2. 并且将字符串变为镜像字符串,例如 ...
- SQL server 存储过程中 列传行
select @exchange=exchange,@coupons_type=coupons_type - FLOOR(exchange))) from points_exchange_svc wh ...
- django反向解析传参
这两天写代码总是有反向解析传参顺带复习了一下反向解析,以下是简单的反向解析 以下是我最近写的很多的反向解析传参 想要实现点击修改将这些从数据库读取的内容传到另一个页面就要通过id来查询,那么我们就需 ...
- GitHub界面初识
现在很多 HR 在招聘程序员的需求都会提到「有 Github 项目者优先」,大部分求职者也会在简历中附上 Github 链接. 作为一个专业的 HR,即便不懂代码,也不能被一个链接唬住.今天我就手 ...
- Beta冲刺(2/7)
目录 摘要 团队部分 个人部分 摘要 队名:小白吃 组长博客:hjj 作业博客:beta冲刺(2/7) 团队部分 后敬甲(组长) 过去两天完成了哪些任务 整理博客 做了点商家数据表格 接下来的计划 做 ...
- 006_设置执行命令提示和unset shell function
一.unset不能unset只读变量 问题: [root@zb1-bdwaimai-inf-wfe-28 ~]# source ~/.bash_profile bash: PROMPT_COMMAND ...
- .Net Core---- 自带Json返回日期带T格式 解决
前段时间再做core的列表显示中(前台代码是在.net core bootstrap集成框架上的(这是效果浏览地址:http://core.jucheap.com[效果地址来自:http://blog ...