python迭代器两个基本方法可供参考_浅析python迭代器和生成器
可迭代对象
概念
一个对象(在Python里面一切都是对象)只要实现了只要实现了__iter__()方法,那么这个对象就是可迭代对象
常见的可迭代对象
集合或序列类型(如list、tuple、set、dict、str)或文件对象
在类中定义了__iter__()方法的对象,可以被认为是 Iterable对象,但自定义的可迭代对象要能在for循环中正确使用,就需要保证__iter__()实现必须是正确的
在类中实现了如果只实现__getitem__()的对象可以通过iter()函数转化成迭代器但其本身不是可迭代对象。所以当一个对象能够在for循环中运行,但不一定是Iterable对象。
针对第一点可以使用print(isinstance([], Iterable)) 进行校验,返回True则是可迭代对象。
关于第二点我们可以通过print(hasattr([], "__iter__"))返回True知道内部实现了__iter__方法,但是这里我们需要注意的是要想被for循环遍历,能够被内置的iter()函数调用并转化成Iterator对象(如下代码所示)
from collections import Iterable
class IterObj:
def __iter__(self):
return self
print(isinstance([], Iterable))
it = IterObj()
print(iter(it))
关于 第四点可以根据如下实例理解
from collections import Iterable, Iterator, Generator
class IterObj:
def __init__(self):
self.a = [3, 5, 7, 11, 13, 17, 19]
def __getitem__(self, i):
return self.a[i]
it = IterObj()
print(isinstance(it, Iterable)) # false
print(hasattr(it, "__iter__")) # false
print(isinstance(iter(it), Iterable)) # true
for i in it:
print(i) # 将打印出3、5、7、11、13、17、19
迭代器
概念
迭代器对象要求支持迭代器协议的对象,在Python中,支持迭代器协议就是实现对象的__iter__()和next()方法。其中__iter__()方法返回迭代器对象本身;next()方法返回容器的下一个元素,在结尾时引发StopIteration异常。简单来说:一个对象实现了__iter__()和__next__()方法,那么它就是一个迭代器对象。
实例
class IterObj:
def __init__(self, n):
self.a = n
self.n = len(self.a)
self.i = 0
def __iter__(self):
return iter(self.a)
def __next__(self):
while self.i < self.n:
v = self.a[self.i]
self.i += 1
return v
else:
self.i = 0
raise StopIteration()
t = IterObj([3, 5, 7, 11, 13, 17, 19])
# 可以通过for遍历
print([ i for i in t])
# 也可以通过next(因为遍历到没有数据时候,抛出异常所以需要捕捉下)
while True:
try:
print(t.__next__())
except:
break
区分iterable,iterator与itertion
itertion: 就是迭代,一个接一个(one after another),是一个通用的概念,比如一个循环遍历某个数组。
iterable: 这个是可迭代对象,属于python的名词,范围也很广,可重复迭代,满足如下其中之一的都是iterable:
可以for循环: for i in iterable
可以按index索引的对象,也就是定义了__getitem__方法,比如list,str;
定义了__iter__方法。可以随意返回。
可以调用iter(obj)的对象,并且返回一个iterator
iterator: 迭代器对象,也属于python的名词,只能迭代一次。需要满足如下的迭代器协议
定义了__iter__方法,但是必须返回自身
定义了next方法,在python3.x是__next__。用来返回下一个值,并且当没有数据了,抛出StopIteration
可以保持当前的状态
优缺点
迭代器优点:
提供了一种通用不依赖索引的迭代取值方式
同一时刻在内存中只存在一个值,更节省内存
迭代器缺点:
取值不如按照索引的方式灵活,不能取指定的某一个值,只能往后取,不能往前去
无法预测迭代器的长度
生成器
概念
生成器就是一种自定义的迭代器,本质为迭代器,但凡函数内包含yield关键字,调用函数不会执行函数体代码,会得到一个返回值,该返回值就是生成器对象。在廖雪峰教程中解释为:在Python中,这种一边循环一边计算的机制,称为生成器(Generator)
注意: 生成器既是可迭代的也是迭代器
定义生成器有两种方式:
列表生成器
使用yield定义生成器函数 (yield是一个语法糖,内部实现了迭代器协议,同时保持状态可以挂起)
列表生成器
from collections import *
g = (x for x in range(3)) # 0~18的偶数生成器
print(isinstance(g, Iterable)) # true
print(isinstance(g, Iterator)) # true
print(isinstance(g, Generator)) # true
print(hasattr(g, "__iter__")) # true
print(hasattr(g, "__next__")) # true
print(next(g)) # 0
print(next(g)) # 1
print(next(g)) # 2
使用yield定义生成器函数
def gen():
for i in range(10):
yield i
# 检索数据,开始执行
a = gen()
print(list(a))
# 调用gen()并没有真实执行函数,而是只是返回了一个生成器对象
# 执行第一次a.next()时,才真正执行函数,执行到yield一个返回值,然后就会挂起,
# 保持当前的名字空间等状态。然后等待下一次的调用,从yield的下一行继续执行。
a = gen()
print(a.__next__())
这里yield的作用就相当于return,这个函数就是顺序地返回[0,9]的之间的自然数,可以通过next()或使用for循环来遍历。当程序遇到yield关键字时,这个生成器函数就返回了,直到再次执行了next()函数,它就会从上次函数返回的执行点继续执行,即yield退出时保存了函数执行的位置、变量等信息,再次执行时,就从这个yield退出的地方继续往下执行。
迭代器和生成器的区别
生成器能做到迭代器能做的所有事,而且因为自动创建了 iter()和 next()方法,生成器显得特别简洁,而且生成器也是高效的,使用生成器表达式取代列表解析可以同时节省内存。
参考链接
来源:oschina
链接:https://my.oschina.net/u/4413809/blog/4659479
python迭代器两个基本方法可供参考_浅析python迭代器和生成器相关推荐
- python迭代器两个基本方法可供参考_2018.8.10 python中的迭代器
主要内容: 1.函数名的使用 2.闭包 3.迭代器 一.函数名的运用 函数名是一个变量,但他是一个特殊的变量,与括号配合可执行函数的变量. 1.函数名的内存地址 def func(): print(' ...
- python中的装饰器、装饰器模式_浅析Python装饰器以及装饰器模式
漫谈 如果作为一个Python入门,不了解Python装饰器也没什么,但是如果作为一个中级Python开发人员,如果再不对python装饰器熟稔于心的话,那么可能并没有量变积累到质变. 我以前也看过很 ...
- python有两个运行程序分别是什么_运行python程序的两种方式
[单选题]I wonder why ________ are so interested in action movies. [单选题]项目经理的职责不包括以下哪项内容 ? [简答题]结合项目的特点和 ...
- python一个函数调用另一个函数中的变量_在Python 中同一个类两个函数间变量的调用方法...
在Python 中同一个类两个函数间变量的调用方法 更新时间:2019年01月31日 15:44:54 作者:wxy_summer 今天小编就为大家分享一篇在Python 中同一个类两个函数间变量的调 ...
- python 保留两位小数方法
参考文章:python 保留两位小数方法 保留两位小数,并做四舍五入处理 方法一:使用字符串格式化 a = 12.345 print("%.2f" % a)# 12.35 方法二: ...
- python迭代器两个基本方法_python迭代器如何实现
迭代是Python最强大的功能之一,是访问集合元素的一种方式.迭代器是一个可以记住遍历的位置的对象.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退. 迭代器有 ...
- 输出九九乘法表——python(两种解决方法,嵌套循环的使用)
用python输出九九乘法表 --------------------两种解决方法 在平时做题时会遇到让我们输出九九乘法表对于这类问题我们可以先做出输出一个直角三角行的形状,在以上的基础上就行代码的修 ...
- 浙大python判断两个字符串是否为变位词_算法2----------变位词
1.背景: 变位词指的是一个单词可以通过改变其他单词中字母的顺序来得到,也叫做兄弟单词,如army->mary. 题1:判断两个字符串s1和s2是否为变位词. 经典的字符串变位词检测问题是比较不 ...
- python的四种内置数字类型_浅析Python数字类型和字符串类型的内置方法
一.数字类型内置方法 1.1 整型的内置方法 作用 描述年龄.号码.id号 定义方式 x = 10 x = int('10') x = int(10.1) x = int('10.1') # 报错 内 ...
最新文章
- 11、InnoDB存储引擎
- 【论文解读】传统图像处理与深度学习又一结合:时空多尺度非局部自相似集成视频超分...
- 完全CSS实现鼠标移上出现层的效果(超简单)
- 嵌入式如何移植php,关于嵌入式web服务器的移植
- jxls向右循环为什么会间隔单元格_VBA中单元格的Offset属性,你是否能灵活的利用呢?...
- 轻松搞定ServerCore初始设置
- dataframe 切片_NumPy中的ndarray与Pandas的Series和DataFrame之间的区别与转换
- VB.NET数据库中插入数据
- SSM房屋租赁系统,房屋合租系统 租房系统 SpringBoot租房系统
- 3.29 判断电脑无线网卡是否支持5GHz频段
- B365装服务器系统,七彩虹b365主板安装win7系统及BIOS设置教程(支持8代cpu)
- Java双亲委派模型是什么、优势在哪、双亲委派模型的破坏
- 顶会竞赛最后5天被Facebook超越,又大比分反超夺冠是什么体验?
- 根据经纬度计算范围_高考地理地理计算专题
- 关于 SecureFx传输远程服务器中文显示乱码 的解决方法
- php中怎样把图片改大,PHP怎么批量修改图片大小?
- Moveit编程——moveit 编程技巧笔记——圆弧轨迹规划+修改轨迹
- Java入门-方法3【入门】兔子繁殖(方法)
- php导出试卷,PHP生成word文档格式试卷的代码
- 我的第一个SAP PROXY ABAP Program(SAP PO 开发五)