Python中的迭代器,可迭代对象,生成器的关系

先用一个关系图来表示他们之间的关系:

基础概念:

可迭代对象

定义:可迭代对象:能够用于for循环的python对象

可迭代对象实现了__iter__方法,该方法返回的是当前对象的迭代器类的实例,可以使用

if '__iter__' in dir(str)来判断对象是否有实现了__iter__方法,可迭代对象实现了可迭代协议:实现__iter__方法

from collections import Iterable,Iterator
class MyIterator:
    def __iter__(self):
        pass
k = MyIterator()
print(isinstance(k,Iterable)) 返回True

迭代器

定义:迭代器:可以被next()函数调用并不断返回下一个值的对象称为迭代器。迭代器原则上只需要实现__next__方法即可,但是python规定迭代器本身必须也是可迭代的,所以必须实现__iter__()方法

迭代器必须实现必须实现__iter__和__next__()方法(python2中是next()方法),

迭代器实现了迭代器协议:(1)实现__iter__方法,返回一个迭代器对象实例。(2)实现__next__()方法返回下一个生成值

class MyListIterator(object):  # 定义迭代器类,其是MyList可迭代对象的迭代器类

    def __init__(self, data):
        self.data = data  # 上边界
        self.now = 0  # 当前迭代值,初始为0

    def __iter__(self):
        return self  # 返回该对象的迭代器类的实例;因为自己就是迭代器,所以返回self

    def __next__(self):  # 迭代器类必须实现的方法
        # pass
        while self.now < self.data:
            self.now += 1
            return self.now - 1  # 返回当前迭代值
        raise StopIteration  # 超出上边界,抛出异常
my = MyListIterator(10)

print(isinstance(my,Iterable),"44444444444444444")
print(isinstance(my,Iterator),"44444444444444444")

生成器

python中一边循环,一边计算的机制叫做生成器

生成器两种生成方式:(1)类似列表生成式:将列表生成式的[]换成()

                                     (2)使用yield关键字返回结果的函数

生成器是特殊的迭代器,其特殊之处在于自动实现了迭代器协议,不需要手动实现两个方法,使用yield关键字返回值,可以使用send方法修改当前迭代值,而普通迭代器需要手动实现,不能修改当前迭代值。

有些文档中说迭代器,是将所有的值都生成存放在内存中,而生成器则是需要元素才临时生成,节省时间,节省空间。

这个结论是错误的,因为迭代器也是需要元素临时生成,这个跟生成器是一致的,实验如下:

from collections import Iterator
from sys import getsizeof
a = [i for i in range(1001)]
print(type(a))
print(getsizeof(a))#4516

b = iter(a)
print(type(b))
print(isinstance(b,Iterator))
print(getsizeof(b))#32
c = (i for i in range(1001))
print(getsizeof(b))    #32

迭代器,生成器遍历完一次就不能从头开始了

a = iter([x for x in range(10)])
for i in a:
    print(i)
print("a第一次遍历完毕")
b= (x for x in range(10))
for i in b:
    print(i)
print("b第一次遍历完毕")
for i in a:
    print(i)
print("a第2次遍历完毕")
for i in b:
    print(i)
print("第2次遍历完毕")


从以下结果可以看出没有执行第二次for循环

0
1
2
3
4
5
6
7
8
9
a第一次遍历完毕
0
1
2
3
4
5
6
7
8
9
b第一次遍历完毕
a第2次遍历完毕
第2次遍历完毕
a = iter([x for x in range(10)])
print(3 in a)
print(3 in a)
这个例子也能说明

True
False

 

可迭代对象,生成器转换成迭代器iter()函数

通过python内置的 iter()方法可以将可迭代对象,生成器转换成为迭代器

iter()函数原理是创建一个可迭代对象或生成器的迭代器类实例,并将它返回

next()方法

next()方法用于调用迭代器或生成器的__next__()方法,返回下一个值

for循环实现原理

在循环遍历自定义容器对象时,会使用python内置函数iter()调用遍历对象的_iter_(self)获得一个迭代器,之后再循环对这个迭代器使用next()调用迭代器对象的_next_(self)。

注意点:_iter_(self)只会被调用一次,而_next_(self)会被调用 n 次,直到出现StopIteration异常。

for item in Iterable 循环的本质就是先通过iter()函数获取可迭代对象Iterable的迭代器,然后对获取到的迭代器不断调用next()方法来获取下一个值并将其赋值给item,当遇到StopIteration的异常后循环结束

总结
凡是可作用于 for 循环的对象都是 Iterable 类型;
凡是可作用于 next() 函数的对象都是 Iterator 类型
集合数据类型如 list 、 dict 、 str 等是 Iterable 但不是 Iterator ,不过可
以通过 iter() 函数获得用个 Iterator 对象。

 

 

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值