1、迭代器

什么是迭代?

迭代是重复反馈过程的活动,其目的通常是为了逼近所需目标或结果。每一次对过程的重复称为一次“迭代”,而每一次迭代得到的结果会作为下一次迭代的初始值。

什么是可迭代对象?

Python中的可迭代对象并不是指某一种具体的数据类型,是指存储了若干个元的容器,且这这个容器中的元素可以通过__iter()____getitem__() 访问。

常用的可迭代对象有:listtupledictstrset、生成器和带有yield的生成器函数。

判断一个对象是否是可迭代对象:

1
2
3
from collections.abc import Iterable

print(isinstance([], Iterable)) # True

获取可迭代对象的迭代器

1
2
3
4
5
item = range(10)
print(type(item)) # <class 'range'>

iterator = iter(item)
print(type(iterator)) # <class 'range_iterator'>

iter() 内部做了什么?

  • 检查对象内部是否实现了__iter__() 如果实现了, 则调用它,获取一个迭代器。
  • 如果没有实现__iter__()方法,但是 实现了__getitem__(),python内部会实现一个迭代器。
  • 如果 以上都失败,则会抛出异常:说明对象不可迭代。

for x in range(10): print(x) 循环执行了什么?

获取可迭代对象的迭代器, 然后在调用next()方法获取下一个元素。

1
2
3
4
5
6
7
8
9
10
11
12
item = range(10)
# 获取迭代器
iterator = iter(item)
item = range(10)
# 获取迭代器
iterator = iter(item)

print(next(iterator)) # 0
print(next(iterator)) # 1
print(next(iterator)) # 2
...
print(next(iterator)) # 9

for 循环即先获取可迭代对象的迭代器,然后在调用next()方法,且在超过迭代对象的长度时,自动捕获错误:StopIteration

1
2
for x in range(10):
print(x)

如何自定义可迭代对象

如上文那样,在一个对象中实现这个__iter__()方法。

1
2
3
4
5
6
7
8
9
10
11
class MyList:
def __init__(self):
self.container = []

def add(self, item):
self.container.append(item)


my_list= MyList()

print(isinstance(my_list, Iterable)) # False
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class MyList:
def __init__(self):
self.container = []

def __iter__(self):
pass

def add(self, item):
self.container.append(item)


my_list= MyList()

print(isinstance(my_list, Iterable)) # True
print(isinstance(my_list, Iterator)) # False

以上类MyList的对象 实现了__iter__(), 所以他是一个可迭代对象,且 print(isinstance(my_list, Iterable)) 判断为True。但是 print(isinstance(my_list, Iterator)) 为False

如何实现一个迭代器呢

如下面代码所示在可迭代对象中再实现__next__() 方法 即可让改对象成为一个迭代器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class MyList:
def __init__(self):
self.container = []

def __iter__(self):
pass

def __next__(self):
pass

def add(self, item):
self.container.append(item)


my_list= MyList()

print(isinstance(my_list, Iterable)) # True
print(isinstance(my_list, Iterator)) # True

综上所述:

对一个可迭代对象调用iter() 方法,其实内部就是寻找__iter__(),并调用,返回的对象当做迭代器。

对一个迭代器对象调用next() 方法,其实内部就是寻找__next__(),并调用,返回可迭代对象的下一个元素。

所以一个迭代器一定是个可迭代对象,但是可迭代对象并不一定是个迭代器。

2、生成器

什么是生成器?

在python 中通俗的理解:一边循环一边计算的机制成为生成器,生成器是一种特殊的迭代器。

3、

4、闭包