博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
迭代器和生成器
阅读量:5078 次
发布时间:2019-06-12

本文共 2740 字,大约阅读时间需要 9 分钟。

一、迭代器

1、定义

  迭代器(Iterator)是一种对象,它能够用来遍历标准模板库容器中的部分或全部元素,每个迭代器对象代表容器中的确定的地址。

满足什么样的条件才能成为迭代器呢?

  • 必须遵从迭代器协议 

迭代器协议:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 。

满足什么样条件的对象才能提供一个next方法呢?

  • 对象内部定义一个__iter__()以及__next__()方法
class Fibonacci(object):    def __init__(self,m):        self.m=m    def __iter__(self):        return self   #自身是一个迭代器    def __next__(self):        n, a, b = 0, 0, 1        while n < self.m:            print(b)            a, b = b, a + b            n += 1f=Fibonacci(5) #f此时就是一个迭代器for  i in f:    print(i)

  如果对象调用__iter__()方法,调用后对象也可以提供一个__next__()方法,但是这样的对象只能被称为可迭代对象(Iterable),因为它不是对象内动实现__iter__()方法,内部自动实现__iter__()方法的对象,才能被称为迭代器(Iterator)。

2、可迭代对象

  可迭代对象与迭代器对象的区别就是看__iter()__方法是不是在对象内部实现的,如果是内部实现的就是迭代器对象,共同点就是都实现了迭代器协议(对象提供了next方法)。

  像listtupledictsetstr等都是直接可以使用for循环的对象都是可迭代对象,使用的就是迭代器协议,但是__iter__()方法是依靠for循环来实现的。

list=[1,2,3]#手动实现__iter__()方法ilist=list.__iter__() print(ilist.__next__())#1print(ilist.__next__())#2print(ilist.__next__())#3

  而在for循环内部也是基于这样的实现方式,不过在for循环内部还进行了异常处理。

#####for循环的实质#######list=[1,2,3]#手动实现__iter__()方法ilist=list.__iter__()while True:    try:        print(ilist.__next__())    except StopIteration as e:        break

3、生成器

  可以理解为一种数据类型,这种数据类型自动实现了迭代器协议,即内部自动实现了__iter__()方法,提供了__next__()方法,所以生成器不仅是可迭代对象而且还是迭代器对象。那么所有可迭代对象拥有的特性,它都拥有,比如for循环。

  如何构造一个生成器呢?

  在一个函数中通过yield关键字自动创建一个生成器函数,yield会自动构建好__next__()和__iter__()方法。

def test():    yield 1    yield 2    yield 3t=test()print(type(t))#
print(t.__next__())#1print(t.__next__())#2print(t.__next__())#3

  进行for循环

for i in test():    print(i)  #1,2,3

  所以生成器就是迭代器的一种,是构造迭代器的工具。

def Fibanocci(m):    n,a,b = 0,0,1    while n < m:        yield b        a,b=b,a+b        n+=1f = Fibanocci(5)   #f为一个迭代器对象,可以将其当作xrange来对待while True:    try:        print(f.__next__())    except StopIteration as e:              break

  在类中也是可以实现迭代器的:

class Fibonacci(object):    def __init__(self,m):        self.m=m    def __iter__(self):        n, a, b = 0, 0, 1        while n < self.m:            yield b            a, b = b, a + b            n += 1f=Fibonacci(5) #f此时就是一个迭代器for i in f:    print(i)

  如何判断一个对象是可迭代对象呢?可以使用isinstance()进行判断。

from collections import Iterableprint(isinstance([], Iterable))#Trueprint(isinstance({}, Iterable))#True

  如何判断是否是生成器对象?可以使用isgenerator()进行判断

from inspect import isgeneratordef test():    yield 1t=test()print(isgenerator(t))#True

  详情查看:

  如何判断是迭代器对象呢?可以使用isinstance()进行判断

from collections import Iteratora="abc"b=iter(a)print(type(b))print(isinstance(b,Iterator))#True

总结:

  迭代器对象内部实现了__iter__()方法以及实现了__next__()方法

  可迭代对象内部没有实现__iter__()方法,必须依靠对象调用__iter__()方法(iter(o))才能成为迭代器对象

  生成器既是可迭代对象,又是迭代器对象,相当于xrange。

 

转载于:https://www.cnblogs.com/shenjianping/p/11042098.html

你可能感兴趣的文章
nodejs fs路径
查看>>
动态规划算法之最大子段和
查看>>
linux c:关联变量的双for循环
查看>>
深入浅出理解zend framework(三)
查看>>
python语句----->if语句,while语句,for循环
查看>>
javascript之数组操作
查看>>
LinkedList源码分析
查看>>
TF-IDF原理
查看>>
用JS制作博客页面背景随滚动渐变的效果
查看>>
JavaScript的迭代函数与迭代函数的实现
查看>>
一步步教你学会browserify
查看>>
Jmeter入门实例
查看>>
亲近用户—回归本质
查看>>
中文脏话识别的解决方案
查看>>
CSS之不常用但重要的样式总结
查看>>
Python编译错误总结
查看>>
URL编码与解码
查看>>
日常开发时遇到的一些坑(三)
查看>>
Eclipse 安装SVN插件
查看>>
深度学习
查看>>