Python基础(12)之迭代器

Python基础(12)之迭代器

微信搜索 zze_coding 或扫描 👉 二维码关注我的微信公众号获取更多资源推送:

我们之前一直在用可迭代对象进行迭代操作,那么到底什么是可迭代对象?
首先我们先回顾一下目前我们所熟知的可迭代对象有哪些:strlisttupledictset
那为什么我们可以称他们为可迭代对象呢?因为他们都遵循了可迭代协议。
什么是可迭代协议?首先我们先看一段代码:

# 正确
for i in '123':
    print(i)

'''
1
2
3
'''

# 错误
for i in 123:
    print(i)

'''
Traceback (most recent call last):
  File ..., line 6, in <module>
    for i in 123:
TypeError: 'int' object is not iterable
'''

注意看报错信息中有这样一句句话:'int' object is not iterable .
翻译过来就是整数类型对象是不可迭代的,iterable 表⽰可迭代的,即遵循可迭代协议。
那么如何进行验证指定数据类型是否符合可迭代协议?我们可以通过 dir 函数来查看类中定义好的所有方法。
在打印结果中寻找 __iter__,如果能找到,那么这个类的对象就是一个可迭代对象。

print('__iter__' in dir(str))

'''
True
'''

我们发现在字符串中可以找到 __iter__,继续看一下 listtupledictset 以及文件对象:

print('__iter__' in dir(tuple))
print('__iter__' in dir(list))
print('__iter__' in dir(open("1.txt", 'w')))
print('__iter__' in dir(set))
print('__iter__' in dir(dict))

'''
True
True
True
True
True
'''

我们发现这几个可以进行 for 循环的对象都有 __iter__ 函数, 包括 range 也有:

print('__iter__' in dir(range(1, 2, 3)))

'''
True
'''

有两个和可迭代对象相关的两个类型分别是:

  • Iterable:可迭代的类型;
  • Iterator:迭代器类型;

所以我们还可以通过 isinstence() 函数来查看一个对象是否是这两个类型的实例:

from collections import Iterable
from collections import Iterator

lst = [1, 2, 3]
lst_iter = lst.__iter__()

print(isinstance(lst, Iterable), isinstance(lst, Iterator))
print(isinstance(lst_iter, Iterable), isinstance(lst_iter, Iterator))

'''
True False
True True
'''

综上,我们可以确定,如果对象中有 __iter__ 函数,那么我们认为这个对象遵守了可迭代协议,就可以获取到相应的迭代器。这里的 __iter__ 是帮助我们获取到对象的迭代器,我们可以使用迭代器中的 __next__() 来逐个获取迭代器中的元素。
说到这里,那么 for 循环的原理到底是什么?继续看代码:

str = 'hello'
str_iter = str.__iter__()
print(str_iter.__next__())
print(str_iter.__next__())
print(str_iter.__next__())
print(str_iter.__next__())
print(str_iter.__next__())
print(str_iter.__next__())  # 这行报错

'''
h
e
l
l
o
Traceback (most recent call last):
  File ..., line 8, in <module>
    print(str_iter.__next__())
StopIteration
'''

可以揭晓了,for 循环的机制其实如下:

str = 'hello'
str_iter = str.__iter__()

while True:
    try:
        item = str_iter.__next__()
        print(item)
    except StopIteration:
        break

'''
h
e
l
l
o
'''

小结

可迭代对象与迭代器:

  • Iterable:可迭代对象,内部包含 __iter__() 函数;
  • Iterator:迭代器,内部包含 __iter__() 同时包含 __next__()

迭代器的特点:

  1. 节省内存;
  2. 惰性机制;
  3. 不能反复, 只能向下执行;

Copyright: 采用 知识共享署名4.0 国际许可协议进行许可

Links: https://www.zze.xyz/archives/python-base-12.html

Buy me a cup of coffee ☕.