c迭代器与生成器
一:迭代器
1.什么是迭代?
1.重复 2.下一次重复是基于上一次的结果
# l=['a','b','c','d']
# count=
# while count < len(l):
# print(l[count]) #count的值基于上一次结果,所以是迭代
# count+=
2.迭代器协议
指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 (只能往后走不能往前退)。
迭代器的优点:
1.提供了一种不依赖索引的迭代方式
2.惰性计算,节省内存
迭代器的缺点:
1.取值不如按照索引取值的方便
2.只能前进,不能后退
3.无法获取长度
判断是否为可迭代对象或者迭代器对象的方法:
# # from collections import Iterable,Iterator
# # print(isinstance(g,Iterator)) #可判断是够为迭代器对象
# def countdown(n):
# print('starting countdown')
#
# while n > 0:
# yield n
# n-=1
# print('stop countdown')
# g=countdown(5) # print(g.__next__())
# print(g.__next__())
# for i in g:
# print(i)
3 迭代器
在介绍迭代器之前,我们先来了解一下容器这个概念。
容器是一种把多个元素组织在一起的数据结构,容器中的元素可以逐个地迭代获取。简单来说,就好比一个盒子,我们可以往里面存放数据,也可以从里面一个一个地取出数据。在python中,属于容器类型地有:list,dict,set,str,tuple.....。容器仅仅只是用来存放数据的,我们平常看到的 l = [1,2,3,4]等等,好像我们可以直接从列表这个容器中取出元素,但事实上容器并不提供这种能力,而是可迭代对象赋予了容器这种能力。
说完了容器,我们在来谈谈迭代器。迭代器与可迭代对象区别在于:__next__()方法。
我们可以采用以下方法来验证一下:
from collections import Iterator f = open('a.txt')
i =
s = ''
d = {'abc':}
t = (, , )
m = {, , , } print(isinstance(i,Iterator))
print(isinstance(s,Iterator))
print(isinstance(d,Iterator))
print(isinstance(t,Iterator))
print(isinstance(m,Iterator))
print(isinstance(f,Iterator)) ########输出结果##########
False
False
False
False
False
True
结果显示:除了文件对象为迭代器,其余均不是迭代器
下面,我们进一步来验证一下:
print(hasattr(i,"__next__"))
print(hasattr(s,"__next__"))
print(hasattr(d,"__next__"))
print(hasattr(t,"__next__"))
print(hasattr(m,"__next__"))
print(hasattr(f,"__next__")) #######结果###########
False
False
False
False
False
True
从输出结果可以表明,迭代器与可迭代对象仅仅就是__next__()方法的有无。
'模拟linux中'
#tail -f a.txt
import time
def tail(filepath,encoding='utf-8'):
with open(filepath,encoding=encoding) as f:
f.seek(,)
while True:
line=f.readline()
if line:
print(line,end='')
# yield line
else:
time.sleep(0.5) tail('b.txt') # for i in g:
# print(i) #tail -f a.txt |grep 'error' # def grep(lines,pattern):
# for line in lines:
# if pattern in line:
# # print(line,end='')
# yield line # g=tail('a.txt')
# print(g) # grep(g,'error') # tail -f a.txt |grep 'error' |grep '' # g1=tail('a.txt')
# g2=grep(g1,'error')
# g3=grep(g2,'')
# for i in g3:
# print(i)
Tips:(字符串,列表,元组,字典,集合,文件对象)这些都不是可迭代对象,只不过在for循环式,调用了他们内部的__iter__方法,把他们变成了可迭代对象,
然后for循环调用可迭代对象的__next__方法去取值,而且for循环会捕捉StopIteration异常,以终止迭代.
StopIteration异常:.__nex___执行后如果没有返回值就会报此异常。
for item in g:
print(item) ###for执行in后面的对象g下面的.__iter__方法,得到一个迭代器k,然后for循环自动k.__next__一次,将得到的结果赋值给item.然后再iter一次变成迭代器赋值给item,直到没有值输出,出现stopiteration异常,for循环可以捕捉到这个异常,然后终止这个循环。 for item in 8:
print(item)
============结果================
TypeError:'int' object is not iterable ###数字是不可迭代对象,下面没有.__iter__方法,所以报错。
Try 可检测异常:
l={'a':1,'x':2,'w':3,'z':4}
l=l.__iter__() #转换成迭代器
while True:
try: #捕捉异常,检测其下缩进的语句是否有异常
i=l.__next__()
print(i)
except StopIteration: #except检测异常
break
二:生成器(生成器的本质就是迭代器)
1.什么是生成器
可以理解为一种数据类型,这种数据类型自动实现了迭代器协议(其他的数据类型需要调用自己内置的__iter__方法),所以生成器是可迭代对象。
按照我们之前所说的,迭代器必须满足两个条件:既有__iter__(),又有__next__()方法。那么生成器是否也有这两个方法呢?答案是,YES。具体来通过以下代码来看看。
def func():
print("one------------->")
yield
print("two------------->")
yield
print("three----------->")
yield
print("four------------>")
yield print(hasattr(func(),'__next__'))
print(hasattr(func(),'__iter__')) #########输出结果###########
True
True
Python有两种不同的方式提供生成器:
1.函数体内包含有yield关键字,该函数的执行结果是生成器(generator).但是,使用yield语句而不是return语句返回结果。yield语句一次返回一个结果,在每个结果中间,挂起函数的状态,以便下次重它离开的地方继续执行.
2.生成器表达式:类似于列表推导,但是,生成器返回按需产生结果的一个对象,而不是一次构建一个结果列表
既然生成器就是迭代器,那么我们是不是也可以通过for循环来遍历出生成器中的内容呢?看下面代码.
def func():
print("one------------->")
yield
print("two------------->")
yield
print("three----------->")
yield
print("four------------>")
yield for i in func():
print(i) #########输出结果########
one-------------> two-------------> three-----------> four------------>
很显然,生成器也可以通过for循环来遍历出其中的内容。
下面我们来看看生成器函数执行流程:
def func():
print("one------------->")
yield
print("two------------->")
yield
print("three----------->")
yield
print("four------------>")
yield g = func() # 生成器 == 迭代器
print(g.__next__())
print(g.__next__())
print(g.__next__())
print(g.__next__())
每次调用g.__next__()就回去函数内部找yield关键字,如果找得到就输出yield后面的值并且返回;如果没有找到,就会报出异常。上述代码中如果在调用g.__next__()就会报错。Python使用生成器对延迟操作提供了支持。所谓延迟操作,是指在需要的时候才产生结果,而不是立即产生结果。这也是生成器的主要好处。
生成器就是迭代器,只能前进不能后退,我们看下这个例子:
#生成器函数补充
# def countdown(n):
# while n > :
# yield n
# n-=
#
# g=countdown()
# print(g.__next__())
# print(g.__next__())
#
# print('='*)
# for i in g:
# print(i)
#
# print('*'*)
# for i in g:
# print(i) =======结果======== ==================== ********************
yiled与return的区别:
x=
y= # if x > y:
# print(x)
# else:
# print(y) # res='aaaaa' if x > y else 'bbbbbbb' #三元表达式---->【 条件成立 条件 条件不成立】
#
# print(res)
2.列表解析<不能加else,条件成立的情况下放到左边。>
# l=[,,,,,]
# l_new=[]
# for i in l:
# if i > :
# l_new.append(i)
# print(l_new)
#列表解析
# res=[i for i in l if i > ]
# print(res)
3.生成器表达式
#g=(i for i in range())
#print (g) #print(next(g)) ##next(g) == g.__next__()
#print(next(g)) ##next(g) == g.__next__()
c迭代器与生成器的更多相关文章
- Python 从零学起(纯基础) 笔记 之 迭代器、生成器和修饰器
Python的迭代器. 生成器和修饰器 1. 迭代器是访问集合元素的一种方式,从第一个到最后,只许前进不许后退. 优点:不要求事先准备好整个迭代过程中的所有元素,仅仅在迭代到某个元素时才计算该元素,而 ...
- Python之模块,迭代器与生成器
本节涉及内容: 1. 迭代器和生成器 2. 递归 3. 字符串格式化 4. 模块 内置模块 自定义模块 第三方模块 5. 序列化的模块 json pickle (一). 迭代器和生成器: 迭代器: ...
- Python之迭代器和生成器
Python 迭代器和生成器 迭代器 Python中的迭代器为类序列对象(sequence-like objects)提供了一个类序列的接口,迭代器不仅可以对序列对象(string.list.tupl ...
- python学习笔记四 迭代器,生成器,装饰器(基础篇)
迭代器 __iter__方法返回一个迭代器,它是具有__next__方法的对象.在调用__next__方法时,迭代器会返回它的下一个值,若__next__方法调用迭代器 没有值返回,就会引发一个Sto ...
- 【Python】迭代器、生成器、yield单线程异步并发实现详解
转自http://blog.itpub.net/29018063/viewspace-2079767 大家在学习python开发时可能经常对迭代器.生成器.yield关键字用法有所疑惑,在这篇文章将从 ...
- 15.python的for循环与迭代器、生成器
在前面学习讲完while循环之后,现在终于要将for循环这个坑填上了.之所以拖到现在是因为for循环对前面讲过的序列.字典.集合都是有效的,讲完前面的内容再来讲for循环会更加容易上手. 首先,for ...
- Python: 迭代器与生成器小结
迭代器与生成器的区别: 1. 迭代器由Class对象创建. 生成器由包含yield表达的Function对象或者Generator Expression创建. 2. 迭代器的原理: (1)由Itera ...
- Python中的迭代器和生成器
本文以实例详解了python的迭代器与生成器,具体如下所示: 1. 迭代器概述: 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后 ...
- Python可迭代对象、迭代器和生成器
Python可迭代对象.迭代器和生成器 python 函数 表达式 序列 count utf-8 云栖征文 python可迭代对象 python迭代器 python生成器 摘要: 8.1 可迭代对象( ...
- Python高手之路【九】python基础之迭代器与生成器
迭代器与生成器 1.迭代器 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退.另外 ...
随机推荐
- Insert 导致死锁的两种情况
官档原文,懒得翻译了 https://dev.mysql.com/doc/refman/5.7/en/innodb-locks-set.html INSERT sets an exclusive lo ...
- dell-7559安装deepin15.8
这大概是我第三次尝试安装deepin了,上一次是显卡问题解决不了,这一次迷迷糊糊问题就解决了. 但是也是尝试了三五十次开机吧233333. 最终是EFI启动,grub引导deepin和win7. 我是 ...
- python3之platform模块
platform模块可以获取操作系统的相关信息. >>> platform.system() #获取系统名称 'Linux' >>> platform.archit ...
- 阿里云centos怎么用xshell5登陆
第一种是用ssh,安装Xshell5 打开XShell 新建会话输入ip 选择新建的会话,点击连接,选择接受并保护,输入root,点击确定 输入密码 已经连接成功了,用Xshell ...
- linux设置静态IP及网卡选择
linux中使用ifconfig命令查看网卡信息时显示为eth1,但是在network-scripts中只有ifcfg-eth0的配置文件,并且里面的NAME="eth0". ...
- 解决 scapy “NameError: global name 'wrpcap' is not defined” 错误
解决 scapy "NameError: global name 'wrpcap' is not defined" 错误 通过 scapy 编写发包脚本时遇到如下错误: Trace ...
- java基础学习之"堆" "栈" "静态存储区" "方法区"
引用部分 java中堆栈(stack)和堆(heap)(还在问静态变量放哪里,局部变量放哪里,静态区在哪里.....进来) Java堆.栈和常量池以及相关String的讲解 等我看完"深入理 ...
- java在window下用cmd (javac、jar)命令行模拟Intellij IDEA软件生成jar包
@@首先最重要的cmd命令: javac ,jar :使用如下(注意[.]不要输错): 1. javac编译: D:\MyWorkSet\idea_hadoop>javac -d .\out\p ...
- @staticmethod和@classmethod
一般来说,要使用某个类的方法,需要先实例化一个对象再调用方法. 而使用@staticmethod或@classmethod,就可以不需要实例化,直接类名.方法名()来调用. 这有利于组织代码,把某些应 ...
- Lua完全自学手册(图文教程)
Programming in Lua程序设计 http://book.luaer.cn/ Lua完全自学手册(图文教程) https://edu.aliyun.com/course/506/les ...