python中创建和使用迭代器 迭代 迭代器和可迭代对象 转

迭代

在计算机中,迭代一般是指反复重复循环,直到到达某个条件为止。在python中可以理解为,能用于for循环的,是可以迭代的。

迭代 iterative

可迭代对象 iterable

迭代器 iterator

迭代器和可迭代对象

一般来说,我们认为能够用于for循环的,就是可迭代对象,能使用next()调用下一个对象的,就是迭代器。这里我们可以发现,之前我们提到的生成器,也是迭代器。

当然,在python中,我们也可以通过代码来判断一个对象是否是可迭代对象,或者是迭代器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
python复制代码from collections.abc import Iterable, Iterator


def check_iterable(x, name):
if isinstance(x, Iterable):
print(name, "是可迭代对象")
else:
print(name, "不是可迭代对象")


def check_iterator(x, name):
if isinstance(x, Iterator):
print(name, "是迭代器")
else:
print(name, "不是迭代器")


if __name__ == "__main__":
t1 = [i for i in range(5)]
check_iterable(t1, "列表")
check_iterator(t1, "列表")

t2 = (i for i in range(5))
check_iterable(t2, "生成器")
check_iterator(t2, "生成器")

t3 = {i: i + 1 for i in range(5)}
check_iterable(t3, "字典")
check_iterator(t3, "字典")

我们执行这个程序,得到了这样的结果

列表 是可迭代对象

列表 不是迭代器

生成器 是可迭代对象

生成器 是迭代器

字典 是可迭代对象

字典 不是迭代器

转换为迭代器

同样是可以通过for循环遍历,为什么生成器就是迭代器,但是列表和字典就不是迭代器呢?

原因是,迭代器从一开始的时候,并没有得到全部的结果,而是通过调用next()得到了下一个结果。虽然迭代器可以被遍历,列表同样也可以被遍历,但是,它们不是一回事。比如,之前我们在生成器中提到的,迭代器可以表示一个无穷无尽的数列,但是列表显然不可以,所以,列表也不会是迭代器。

但是,我们可以通过iter(),创建迭代器对象,比如说,我们通过iter()将列表转换为迭代器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
python复制代码from collections.abc import Iterator


def check_iterator(x, name):
if isinstance(x, Iterator):
print(name, "是迭代器")
else:
print(name, "不是迭代器")


if __name__ == "__main__":
t1 = [i for i in range(5)]
check_iterator(t1, "列表转换前")

t2 = iter(t1)
check_iterator(t2, "列表转换后")

print(t2)

print(next(t2))

从这里,我们可以看出,转换前的列表不是迭代器,使用iter转换后是迭代器,同时也可以使用next()函数。

创建迭代器

如果你要创建一个类作为迭代器,那么要实现两个方法

iter() 该方法返回一个迭代器,此处可以返回自己

next() 该方法返回下一个迭代器对象

其中,如果你要为迭代器设置终止标志的话,需要抛出StopIteration异常,通过for循环遍历该迭代器时,会在StopIteration处结束

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
python复制代码from collections.abc import Iterator


def check_iterator(x, name):
if isinstance(x, Iterator):
print(name, "是迭代器")
else:
print(name, "不是迭代器")


class XiaIterator:
"""
作者:瞎老弟
时间:2021-10-29
联系方式:qq1413274264
说明:一个自建的迭代器类
"""

def __init__(self, num):
self.num = num

def __iter__(self):
self.s = 0
return self

def __next__(self):
if self.s < self.num:
self.s += 1
return self.s
else:
# 通过for循环使用,会在StopIteration处停止
# 如果是通过next()调用,会在最后抛出StopIteration异常
raise StopIteration


if __name__ == "__main__":
for i in XiaIterator(20):
print(i)

check_iterator(XiaIterator(20), "瞎老弟自建的迭代器类")

补充说明

你可能在其他地方,也能看到老版本的写法,如下所示

from collections.abc import Iterator 新版本是这样写的

from collections import Iterator 老版本是这样写的

这两种方式没什么区别,是一样的,只不过后面的那种在python的新版本中不再允许被使用了而已,如果你使用的是3.8以及以前的python版本,使用老版本的写法也是一样的。

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%