可迭代对象和迭代器

可迭代对象(iterable)

定义

实现了__iter__方法的对象称为可迭代对象,在python中,可迭代对象有字符串、列表、元组、字典、集合等

创建可迭代对象

class MyNumbers:

    def __init__(self):
        self.a = 1

    def __iter__(self):
        return self

my_numbers = MyNumbers()

判断

判断对象是否是可迭代对象

from collections.abc import Iterable

print(isinstance("123", Iterable))        #字符串:True
print(isinstance([1, 2, 3], Iterable))    #列表:True
print(isinstance((1, 2, 3), Iterable))    #元组:True
print(isinstance({"a": 1, "b": 2}, Iterable))   #字典:True
print(isinstance({1, 2, 3}, Iterable))    #集合:True
print(isinstance(open("test.txt", "r"), Iterable))  #文件:True
print(isinstance(my_numbers, "r"), Iterable))   #my_numbers对象:True

也可以去源码里查看,比如源码里的list类实现了__iter__方法

迭代器(iterator)

定义

实现了__iter__和__next__方法的对象称为迭代器,__iter__返回一个特殊的迭代器对象self,__next__返回下一个可用元素,如果没有元素,会抛出StopIteration异常

内置的迭代器

map()、zip()、enumerate()、filter()、文件对象等都是迭代器

创建迭代器

class MyNumbers:

    def __init__(self):
        self.a = 1

    def __iter__(self):
        return self

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

my_numbers = MyNumbers()
print(next(my_numbers))  #1
print(next(my_numbers))  #2
print(next(my_numbers))  #3

判断

from collections.abc import Iterator

print(isinstance(my_numbers, Iterator))  #my_numbers对象:True

特点

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

可迭代对象和迭代器的关系

用可迭代对象创建迭代器

可迭代对象实现了__iter__方法,但没有实现__next__方法,实际上可迭代对象调用iter()方法时,它会自动调用__iter__方法,而__iter__方法的作用是返回一个特殊的迭代器,因此实现了用可迭代对象创建迭代器

用列表创建迭代器

L = [1, 2, 3]
I = iter(L)
print(next(I))
print(next(I))
print(next(I))
print(next(I))  #没有下一个元素,抛出异常
print(next(I))


# 运行结果
Traceback (most recent call last):
  File "E:/virtual_workshop/everyday/test/iterators.py", line 80, in <module>
    print(next(I))
StopIteration
1
2
3

为了避免异常的情况,可以使用for或者next加异常捕获来遍历元素
for循环

L = [1, 2, 3]
I = iter(L)

for i in I:
    print(i, end=" ")


# 运行结果
1 2 3

next加异常捕获

import sys

L = [1, 2, 3]
I = iter(L)

while True:
    try:
        print(next(I), end=" ")
    except StopIteration:
        sys.exit()


# 运行结果
1 2 3

用字典创建迭代器

D = {"a":1, "b": 2, "c": 3}
I = iter(D)

for i in I:
    print(i, end=" ")


# 运行结果
a b c

字典中有一个迭代器(但不能说字典本身就是迭代器),在迭代环境中,会自动一次返回一个key

D = {"a":1, "b": 2, "c": 3}

for key in D:
    print(key, end=" )


# 运行结果
a b c

关系

  • 迭代器一定是可迭代的,但可迭代对象不是迭代器
  • 可以用可迭代对象创建迭代器
  • 可迭代对象必须实现__iter__方法,不能实现__next__方法
  • 可迭代对象与迭代器都有__iter__方法,但可迭代对象的__iter__用于实例化一个迭代器对象,而迭代器中的__iter__用于返回迭代器本身,与__next__共同完成迭代器的迭代

参考文章

《Python3 迭代器与生成器》
《python3 迭代器》
《Python3学习笔记(十四):可迭代对象、迭代器和生成器》
《如何理解Python中的可迭代对象、迭代器和生成器》

posted @ 2020-05-03 15:33  cnhkzyy  阅读(255)  评论(0编辑  收藏  举报