python3 迭代器

可迭代(Iterable)对象与迭代器(Iterator)

可迭代对象  

凡是可以返回一个迭代器的对象都可称之为可迭代对象

判断对象是否Iterable: 

from collections import Iterable

print(isinstance([],Iterable)) #True
print(isinstance((),Iterable)) #True
print(isinstance({},Iterable)) #True
print(isinstance('ABC',Iterable)) #True
print(isinstance((x for x in range(10)),Iterable)) #True
print(isinstance(100,Iterable))#False

迭代器

迭代是Python最强大的功能之一,是访问集合元素的一种方式。

任何实现了__iter____next__()方法的对象都是迭代器,__iter__返回迭代器自身,__next__返回容器中的下一个值,如果容器中没有更多元素了,则抛出StopIteration异常。

  • 迭代器是一个可以记住遍历的位置的对象。
  • 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。
  • 迭代器只能往前不会后退。
  • 迭代器有两个基本的方法:iter() 和 next()。
  • 生成器一定是迭代器(反之不成立)

可以使用迭代器进行访问的对象:

  • 序列:字符串、列表、元组

  • 非序列:字典、文件

  • 自定义类:用户自定义的类实现了__iter__()或__getitem__()方法的对象  

判断对象是否是Iterator:

from collections import Iterator

print(isinstance((x for x in range(10)),Iterator)) #True
print(isinstance([],Iterator)) #False
print(isinstance({},Iterator)) #False
print(isinstance('abc', Iterator)) #False

生成器都是 Iterator 对象,但 list、 dict、 str 虽然是 Iterable,却不是Iterator。

把Iterable对象变成 Iterator:

from collections import Iterator

print(isinstance(iter([]),Iterator)) #True
print(isinstance(iter('ABC'),Iterator)) #True

访问迭代器中的元素

使用next()访问

使用next()函数输出迭代器中的下一个值,没有更多的元素时,抛出StopIteration 的错误。

list=[1,2,3,4]
it = iter(list)    # 创建迭代器对象
print (next(it))
print (next(it))
print (next(it))
print (next(it))
print (next(it))

输出:

1
2
3
4
Traceback (most recent call last):
  File "E:/ru/231n/exer.py", line 7, in <module>
    print (next(it))
StopIteration

这是因为 Python 的 Iterator 对象表示的是一个数据流, Iterator 对象可以被 next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration 错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过 next()函数实现按需计算下一个数据,所以 Iterator 的计算是惰性的,只有在需要返回下一个数据时它才会计算。
Iterator 甚至可以表示一个无限大的数据流,例如全体自然数。而使用list 是永远不可能存储全体自然数的。

使用for语句访问

使用for语句遍历,这样就不需要关心 StopIteration 的错误。 

list=[1,2,3,4]
it = iter(list)    # 创建迭代器对象
for x in it:
    print (x, end=" ")  #1 2 3 4 

创建一个迭代器

把一个类作为一个迭代器使用需要在类中实现两个方法 __iter__() 与 __next__() 。

__iter__() 方法返回一个特殊的迭代器对象, 这个迭代器对象实现了 __next__() 方法并通过 StopIteration 异常标识迭代的完成。

__next__() 方法会返回下一个迭代器对象。

创建一个返回数字的迭代器,初始值为 1,逐步递增 1:

class MyNumbers:
    def __iter__(self):
        self.a = 1
        return self

    def __next__(self):
        x = self.a
        self.a += 1
        return x


myclass = MyNumbers()
myiter = iter(myclass)

print(next(myiter))  #1
print(next(myiter))  #2
print(next(myiter))  #3
print(next(myiter))  #4
print(next(myiter))  #5

StopIteration

StopIteration 异常用于标识迭代的完成,防止出现无限循环的情况,在  __next__() 方法中我们可以设置在完成指定循环次数后触发 StopIteration 异常来结束迭代。

在 20 次迭代后停止执行:

class MyNumbers:
    def __iter__(self):
        self.a = 1
        return self

    def __next__(self):
        if self.a <= 20:
            x = self.a
            self.a += 1
            return x
        else:
            raise StopIteration


myclass = MyNumbers()
myiter = iter(myclass)

for x in myiter:
    print(x)

输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
posted @ 2018-11-26 09:58  刘-皇叔  阅读(1101)  评论(0编辑  收藏  举报