有关迭代器、迭代器对象、生成器、可迭代对象的知识点的学习总结

目录

  1. 1. 迭代器
    1. 1.1迭代器
    2. 1.2 迭代器对象
      1. 1. __next__方法
      2. 2. for循环
  2. 2. 生成器
  3. 3. 可迭代对象
  4. 4. 补充知识点
    1. 4.1 自定义一个range
      1. 4.1.1 基于可迭代对象实现
      2. 4.1.2 基于生成器实现
    2. 4.2 是可迭代对象的常见数据类型
    3. 4.3 python中判断类型
  5. 5.几段应用知识点的代码
    1. 5.1 例1

1. 迭代器

1.1迭代器

  1. 类中定义了__iter____next__两个方法
  2. __iter__方法返回self
  3. __next__方法返回下一个数据,如果没有数据了,则需要抛出一个StopIteration的异常
1
2
3
4
5
6
7
8
9
10
11
12
class Exa:
def __init__(self):
self.counter = 0

def __iter__(self):
return self

def __next__(self):
self.counter += 1
if self.counter == 5:
raise StopIteration()
return self.counter

1.2 迭代器对象

迭代器对象就是对迭代器的实例化

1. __next__方法

可以通过反复执行__next__方法获取其中的值,有两种调用方式:

1
2
3
obj1 = Exa()
v1 = obj1.__next__()
v1 = next(obj1) # 通过内置函数

其中,Exa是迭代器的类名,obj1是对迭代器实例化的对象

2. for循环

可以对迭代器对象进行for循环

1
2
3
obj2 = Exa()
for o in obj2:
print(o)

过程

① 首先会执行迭代器对象中的__iter__方法并获取返回值(返回self)

②然后会反复执行next(obj2)

③直到没有数据了,抛出异常

2. 生成器

定义一个函数,函数中只要有yield,这个函数就被称为生成器函数。

1
2
3
def func():
a = [0, 1, 2, 3, 4]
yield a

生成器函数() :就是生成器对象(内部是根据生成器类generator创建的对象)。

生成器类的内部也声明了:

1
__iter__、```__next__

方法。

如果按照迭代器的定义来看,生成器也可以认为是一种特殊的迭代器

且生成器可以使用next方法,可以进行for循环

3. 可迭代对象

如果一个类中有__iter__方法且返回一个迭代器对象 ,则我们称以这个类创建的对象为可迭代对象。

1
2
3
4
5
6
7
8
9
10
class Foo(object):

def __iter__(self):
return 迭代器对象(生成器对象)

obj = Foo() # obj 是可迭代对象

# 可迭代对象可以使用for来进行循环,在循环的内部其实是先执行__iter__方法,获取其迭代器对象,然后再在内部执行这个迭代器对象的next功能,逐步取值。
for item in obj:
pass
1
2
v1 = range(100)  # 返回可迭代对象
dir(v1) # 输出中包含 __iter__方法,但无__next__方法

列表、元组、字典、集合常见的数据类型全是可迭代对象

4. 补充知识点

4.1 自定义一个range

4.1.1 基于可迭代对象实现

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
class IterRange(object):   # 迭代器
def __init__(self, num):
self.num = num
self.counter = -1

def __iter__(self):
return self

def __next__(self):
self.counter += 1
if self.counter == self.num:
raise StopIteration()
return self.counter


class Irange(object): # 可迭代对象
def __init__(self, max_num):
self.max_num = max_num

def __iter__(self):
return IterRange(self.max_num)


# for循环 Irange
for i in Irange(10):
print(i)


# 输出:
0
1
2
3
4
5
6
7
8
9

4.1.2 基于生成器实现

1
2
3
4
5
6
7
8
9
10
11
12
class Irange(object):
def __init__(self, max_num):
self.max_num = max_num

def __iter__(self):
counter = 0
while counter < self.max_num:
yield counter
counter += 1

for i in Irange(10):
print(i)

4.2 是可迭代对象的常见数据类型

1
2
3
v1 = list([1, 2, 3, 4])
# v1是一个可迭代对象,因为在列表中声明了一个__iter__方法,且返回一个迭代器对象
dir(v1) # 可用此验证

列表、元组、字典、集合常见的数据类型全是可迭代对象

4.3 python中判断类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from collections.abc import Iterator, Iterable

# Iterable:判断是否有__iter__方法,且返回迭代器
# Iterator:判断是否有__iter__和__next__方法

v1 = [1, 2, 3, 4]
print(isinstance(v1, Iterable)) # True
print(isinstance(v1, Iterator)) # False
# v1是可迭代对象,其中 有__iter__,无__next__

v2 = v1.__iter__()
print(isinstance(v2, Iterable)) # True
print(isinstance(v2, Iterator)) # True
# v2是迭代器对象,其中 有__iter__,有__next__

iterable:返回的可能是可迭代对象,也可能是迭代器对象

iterator:返回的是迭代器对象

5.几段应用知识点的代码

结合例子加深理解

5.1 例1

1
2
3
4
5
6
7
8
9
10
def test():
for i in range(4):
yield i

g = test()
g1 = (i for i in g)
g2 = (i for i in g1)
g3 = (i for i in list(g1))
print(list(g1))
print(list(g2))

庖丁解牛