迭代器 生成器

一 什么是迭代器协议

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 line
 
def grep(target,lines):
    for line in lines:
        if target in  line:
            yield line
 
line_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 urlopen
def 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 迭代器 生成器的更多相关文章

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

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

  2. Python 迭代器&生成器

    1.内置参数     Built-in Functions     abs() dict() help() min() setattr() all() dir() hex() next() slice ...

  3. Python 迭代器&生成器,装饰器,递归,算法基础:二分查找、二维数组转换,正则表达式,作业:计算器开发

    本节大纲 迭代器&生成器 装饰器  基本装饰器 多参数装饰器 递归 算法基础:二分查找.二维数组转换 正则表达式 常用模块学习 作业:计算器开发 实现加减乘除及拓号优先级解析 用户输入 1 - ...

  4. python迭代器,生成器,推导式

    可迭代对象 字面意思分析:可以重复的迭代的实实在在的东西. list,dict(keys(),values(),items()),tuple,str,set,range, 文件句柄(待定) 专业角度: ...

  5. 4.python迭代器生成器装饰器

    容器(container) 容器是一种把多个元素组织在一起的数据结构,容器中的元素可以逐个地迭代获取,可以用in, not in关键字判断元素是否包含在容器中.通常这类数据结构把所有的元素存储在内存中 ...

  6. python迭代器生成器

    1.生成器和迭代器.含有yield的特殊函数为生成器.可以被for循环的称之为可以迭代的.而可以通过_next()_调用,并且可以不断返回值的称之为迭代器 2.yield简单的生成器 #迭代器简单的使 ...

  7. Python迭代器生成器,私有变量及列表字典集合推导式(二)

    1 python自省机制 这个是python一大特性,自省就是面向对象的语言所写的程序在运行时,能知道对象的类型,换句话说就是在运行时能获取对象的类型,比如通过 type(),dir(),getatt ...

  8. Python迭代器生成器,模块和包

      1.迭代器和生成器 2.模块和包 1.迭代器 迭代器对象要求支持迭代器协议的对象,在Python中,支持迭代器协议就是实现对象的__iter__()和__next__()方法.    其中__it ...

  9. python迭代器生成器-迭代器和list区别

    迭代 生成 for循环遍历的原理 for循环遍历的原理就是迭代,in后面必须是可迭代对象 为什么要有迭代器 对于序列类型:字符串.列表.元组,我们可以使用索引的方式迭代取出其包含的元素.但对于字典.集 ...

随机推荐

  1. ER图

    E-R图也称实体-联系图(Entity Relationship Diagram), 提供了表示实体类型.属性和联系的方法,用来描述现实世界的概念模型. 它是描述现实世界概念结构模型的有效方法.是表示 ...

  2. 1.Java关键字和保留字

    关键字和保留字 http://www.cnblogs.com/wwxbi/p/4292170.html 访问控制 private protected public 类,方法和变量修饰符 abstrac ...

  3. Angular -ui - BootStrap组件的解释以及使用

    关于UI BootStrap UI BootStrap 是angularUI团队用纯粹angularJS语法编写的Bootstrap组件. 1. 关于ng-router(angular-router. ...

  4. 解决 python 中,时间日期不能序列化的问题

    在python 中, 你在数据库娶到了数据中如果含有时间日期,那么你在向前端作为json对象传递的时候呢,就会报错.大致如下: TypeError: datetime.datetime(2017, 1 ...

  5. [JLOI2012] 树

    Description 在这个问题中,给定一个值S和一棵树.在树的每个节点有一个正整数,问有多少条路径的节点总和达到S.路径中节点的深度必须是升序的.假设节点1是根节点,根的深度是0,它的儿子节点的深 ...

  6. Docker(四):Docker 三剑客之 Docker Compose

    前两篇文章我们介绍了 Dockerfile 的使用Docker(二):Dockerfile 使用介绍,我们知道使用一个 Dockerfile 模板文件可以定义一个单独的应用容器,如果需要定义多个容器就 ...

  7. java基础学习系列二

    循环语句 1,for(){} 2,while(){} 3,do{}while() continue和break用法 break是结束循环 continue结束本次循环

  8. 最小生成数(并查集)Kruskal算法

    并查集:使用并查集可以把每个连通分量看作一个集合,该集合包含连通分量的所有点.这两两连通而具体的连通方式无关紧要,就好比集合中的元素没有先后顺序之分,只有属于和不属于的区别.#define N 100 ...

  9. 大数据 --> 大数据关键技术

    大数据关键技术 大数据环境下数据来源非常丰富且数据类型多样,存储和分析挖掘的数据量庞大,对数据展现的要求较高,并且很看重数据处理的高效性和可用性. 传统数据处理方法的不足 传统的数据采集来源单一,且存 ...

  10. WEB端线上偶现问题如何复现?

    1.抓取出现问题的日志,还原操作过程,分析 每个过程中数据是否正常?是否有重复请求 2.询问当时操作员执行了哪些操作,尽可能多的了解事发经过 3.通过查看日志,数据库等信息,找到发生问题的节点, 比如 ...