python 迭代器 生成器
迭代器 生成器
一 什么是迭代器协议
1.迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 (只能往后走不能往前退)
2.可迭代对象:实现了迭代器协议的对象(如何实现:对象内部定义一个__iter__()方法)
3.协议是一种约定,可迭代对象实现了迭代器协议,python的内部工具(如for循环,sum,min,max函数等)使用迭代器协议访问对象。
|
1
2
3
4
5
6
7
|
#序列类型 字符串,列表,元组都有下标,你用上述的方式访问#非序列类型 字典,集合,文件 #for循环就是基于迭代器协议提供了一个统一的可以遍历所有对象的方法,#即在遍历之前,先调用对象的__iter__方法将其转换成一个迭代器,#然后使用迭代器协议去实现循环访问,这样所有的对象就都可以通过for循环来遍历了,#而且你看到的效果也确实如此,这就是无所不能的for循环,觉悟吧,年轻人 |
迭代器
|
1
2
3
|
#可迭代的:只要对象本身有__iter__方法,那它就是可迭代的#执行对象下的__iter__方法,得到的结果就是迭代器 |
为什么要用迭代器:
|
1
2
3
4
5
6
7
|
#优点# 1:迭代器提供了一种不依赖于索引的取值方式,这样就可以遍历那些没有索引的可迭代对象了(字典,集合,文件)# 2:迭代器与列表比较,迭代器是惰性计算的,更节省内存#缺点:# 1:无法获取迭代器的长度,使用不如列表索引取值灵活# 2:一次性的,只能往后取值,不能倒着取值 |
迭代器的用途
|
1
|
for循环 |
二.生成器
一.函数
1.什么是生成器?
|
1
|
可以理解为一种数据类型,这种数据类型自动实现了迭代器协议(其他的数据类型需要调用自己内置的__iter__方法),所以生成器就是可迭代对象 |
2.生成器分类及在python中的表现形式:(Python有两种不同的方式提供生成器)
|
1
2
3
4
|
1.生成器函数:常规函数定义,但是,使用yield语句而不是return语句返回结果。yield语句一次返回一个结果,在每个结果中间,挂起函数的状态,以便下次重它离开的地方继续执行2.生成器表达式:类似于列表推导,但是,生成器返回按需产生结果的一个对象,而不是一次构建一个结果列表 |
3.为何使用生成器之生成器的优点
|
1
2
|
Python使用生成器对延迟操作提供了支持。所谓延迟操作,是指在需要的时候才产生结果,而不是立即产生结果。这也是生成器的主要好处。 |
4.生成器小结:
|
1
2
3
|
1.是可迭代对象2.实现了延迟计算,省内存啊3.生成器本质和其他的数据类型一样,都是实现了迭代器协议,只不过生成器附加了一个延迟计算省内存的好处,其余的可迭代对象可没有这点好处,记住喽!!! |
5.yield的功能:
|
1
2
3
|
1.相当于把__iter__和__next__方法封装到函数内部2.与return比,return只能返回一次,而yield能返回多次3.函数暂停已经继续运行的状态是通过yield保存的 |
#yield表达形式:
food=yield #生成器.send与next(生成器)区别:
1.如果函数内yeild是表达式形式,那么必须先next(e)
2.二者的共同之处都可以让函数在上次暂时的位置继续运行不同之处在于send在出发下一次的执行时,会顺便给yield传一个值 yield表达式
yield表达式
tail 命令实现
#/usr/bin/env python
import time
#定义阶段:定义俩生成器函数
def tail(file_path):
with open(file_path,'r') as f:
f.seek(0,2)
while True:
line=f.readline() #最后一行 if not line:
time.sleep(0.3)
continue
else:
#print(line,end='')
yield line def grep(pattern,lines):
for line in lines:
if pattern in line:
yield line #调用阶段:得到俩生成器对象
g1=tail('/tmp/a.txt')
g2=grep('error',g1) #next触发执行g2生成器函数
for i in g2:
print(i) tail -f /tmp/a.txt | grep error
二.生成器表达式

#三元表达式
name='alex'
name='linhaifeng'
res='SB' if name == 'alex' else 'shuai'
print(res) #列表解析
li = [i for i in range(10) ]
li = [i for i in range(10) if i > 5]

三.协程
def init():
def wrapper(*args,**kwargs):
obj = func(*args,**kwargs)
next(obj)
return obj
return wrapper @init #food = init(food)
def food(name):
print("%s start to eat" % name)
food_list = []
while True:
food = yield food_list
food_list.append(food)
print("%s eat %s" % (name,food_list)) e = food("alex")
e.send("apple")
e.send("apple")
e.send("apple") 协程包子
协程包子
#grep -rl 'python' C:\egon
import os,time
def init(func):
def wrapper(*args,**kwargs):
res=func(*args,**kwargs)
next(res)
return res
return wrapper #找到一个绝对路径,往下一个阶段发一个
@init
def search(target):
'找到文件的绝对路径'
while True:
dir_name=yield #dir_name='C:\\egon'
print('车间search开始生产产品:文件的绝对路径')
time.sleep(2)
g = os.walk(dir_name)
for i in g:
# print(i)
for j in i[-1]:
file_path = '%s\\%s' % (i[0], j)
target.send(file_path) @init
def opener(target):
'打开文件,获取文件句柄'
while True:
file_path=yield
print('车间opener开始生产产品:文件句柄')
time.sleep(2)
with open(file_path) as f:
target.send((file_path,f)) @init
def cat(target):
'读取文件内容'
while True:
file_path,f=yield
print('车间cat开始生产产品:文件的一行内容')
time.sleep(2)
for line in f:
target.send((file_path,line)) @init
def grep(pattern,target):
'过滤一行内容中有无python'
while True:
file_path,line=yield
print('车间grep开始生产产品:包含python这一行内容的文件路径')
time.sleep(0.2)
if pattern in line:
target.send(file_path) @init
def printer():
'打印文件路径'
while True:
file_path=yield
print('车间printer开始生产产品:得到最终的产品')
time.sleep(2)
print(file_path) g=search(opener(cat(grep('python',printer()))))
g.send('C:\\egon')
g.send('D:\\dir1')
g.send('E:\\dir2') 协程windows 查找文件
协程windows 查找文件
import os def init(func):
def wrapper(*args,**kwargs):
obj = func(*args,**kwargs)
next(obj)
return obj
return wrapper @init
def search(target):
while True:
dir_name = yield
obj = os.walk(dir_name)
for file in obj:
for path in file[-1]:
file_path = "%s/%s" % (file[0],path)
target.send(file_path) @init
def opener(target):
while True:
file_path = yield
with open(file_path) as f:
target.send((file_path,f))
@init
def cat(target):
while True:
file_path,file = yield
for line in file:
target.send((file_path,line))
@init
def grep(pattern,target):
while True:
file_path,line = yield
if pattern in line:
target.send(file_path)
@init
def print_file():
while True:
file_path = yield
print(file_path) g = search(opener(cat(grep("a",print_file()))))
g.send("/Users/centos/Desktop/example") 协程Linux查找文件
协程Linux查找文件
四.Example 两题

|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
def cat(name): with open("a","r",encoding="utf8") as name: for line in name: yield linedef grep(target,lines): for line in lines: if target in line: yield lineline_cat = cat("a")grep_cat = grep("apple",line_cat)for line in grep_cat: print(line.strip()) |

|
1
2
3
4
5
6
7
8
9
10
|
from urllib.request import urlopendef get(): while True: url=yield res=urlopen(url).read() print(res)g=get()next(g)g.send('http://www.python.org') |
http://www.cnblogs.com/linhaifeng/articles/6133014.html
python 迭代器 生成器的更多相关文章
- Python迭代器生成器与生成式
Python迭代器生成器与生成式 什么是迭代 迭代是重复反馈过程的活动,其目的通常是为了逼近所需目标或结果.每一次对过程的重复称为一次"迭代",而每一次迭代得到的结果会作为下一次迭 ...
- Python 迭代器&生成器
1.内置参数 Built-in Functions abs() dict() help() min() setattr() all() dir() hex() next() slice ...
- Python 迭代器&生成器,装饰器,递归,算法基础:二分查找、二维数组转换,正则表达式,作业:计算器开发
本节大纲 迭代器&生成器 装饰器 基本装饰器 多参数装饰器 递归 算法基础:二分查找.二维数组转换 正则表达式 常用模块学习 作业:计算器开发 实现加减乘除及拓号优先级解析 用户输入 1 - ...
- python迭代器,生成器,推导式
可迭代对象 字面意思分析:可以重复的迭代的实实在在的东西. list,dict(keys(),values(),items()),tuple,str,set,range, 文件句柄(待定) 专业角度: ...
- 4.python迭代器生成器装饰器
容器(container) 容器是一种把多个元素组织在一起的数据结构,容器中的元素可以逐个地迭代获取,可以用in, not in关键字判断元素是否包含在容器中.通常这类数据结构把所有的元素存储在内存中 ...
- python迭代器生成器
1.生成器和迭代器.含有yield的特殊函数为生成器.可以被for循环的称之为可以迭代的.而可以通过_next()_调用,并且可以不断返回值的称之为迭代器 2.yield简单的生成器 #迭代器简单的使 ...
- Python迭代器生成器,私有变量及列表字典集合推导式(二)
1 python自省机制 这个是python一大特性,自省就是面向对象的语言所写的程序在运行时,能知道对象的类型,换句话说就是在运行时能获取对象的类型,比如通过 type(),dir(),getatt ...
- Python迭代器生成器,模块和包
1.迭代器和生成器 2.模块和包 1.迭代器 迭代器对象要求支持迭代器协议的对象,在Python中,支持迭代器协议就是实现对象的__iter__()和__next__()方法. 其中__it ...
- python迭代器生成器-迭代器和list区别
迭代 生成 for循环遍历的原理 for循环遍历的原理就是迭代,in后面必须是可迭代对象 为什么要有迭代器 对于序列类型:字符串.列表.元组,我们可以使用索引的方式迭代取出其包含的元素.但对于字典.集 ...
随机推荐
- http协议中302和303的区别
http1.0协议中只有302码,没有303状态码:http1.1,在默认情况下,很多服务端基础程序,为了兼容http1.0,在遇到本应响应303时,也给客户端响应了302. 碰到的问题: 场景: 在 ...
- JS基础三
1.delete删除对对象的属性和方法的定义.强制解除对它的引用,将其设置为 undefined delete 运算符不能删除开发者未定义的属性和方法. 2.void 运算符对任何值返回 undefi ...
- Docker + webpack 打包前端项目
码云代码地址: https://gitee.com/caonimashi/docker_deployment_front_end 构建基础镜像: 1.下载一个 Apline Linux 操作系统 ...
- Spring Boot应用的后台运行配置
酱油一篇,整理一下关于Spring Boot后台运行的一些配置方式.在介绍后台运行配置之前,我们先回顾一下Spring Boot应用的几种运行方式: 运行Spring Boot的应用主类 使用Mave ...
- Java NIO之套接字通道
1.简介 前面一篇文章讲了文件通道,本文继续来说说另一种类型的通道 -- 套接字通道.在展开说明之前,咱们先来聊聊套接字的由来.套接字即 socket,最早由伯克利大学的研究人员开发,所以经常被称为B ...
- Algorithm --> 最长回文子串
1.中心扩展 中心扩展就是把给定的字符串的每一个字母当做中心,向两边扩展,这样来找最长的子回文串.算法复杂度为O(N^2). 但是要考虑两种情况: 1.像aba,这样长度为奇数. 2.想abba,这样 ...
- KVM之五:KVM日常管理常用命令
1.查看.编辑及备份KVM 虚拟机配置文件 以及查看KVM 状态: 1.1.KVM 虚拟机默认的配置文件在 /etc/libvirt/qemu 目录下,默认是以虚拟机名称命名的.xml 文件,如下,: ...
- 循环while do---while for循环
一.循环结构 (.^▽^) 1.循环不是无休止进行的,满足一定条件的时候循环才会继续,称为"循环条件",循环条件不满足的时候,循环退出 2.循环结构是反复进行相同的或类似的一系列操 ...
- 外部 Storage Provider - 每天5分钟玩转 Docker 容器技术(149)
如果 Kubernetes 部署在诸如 AWS.GCE.Azure 等公有云上,可以直接使用云硬盘作为 Volume,下面是 AWS Elastic Block Store 的例子: 要在 Pod 中 ...
- 极光征文 | 写写文章就能赢 Filco,岂不美滋滋
由极光社区举办的第二届征文大赛 --「我和极光的那些事儿」又来啦! 在简书平台发布文章并投稿至「我和极光的那些事」专题,只要参与就能 100% 获得京东购物卡,更有机会赢取象征信仰的 Filco 机械 ...