生成器和迭代器都可用于循环生成数据,而迭代器需要一次性存储所有元素,而生成器可以逐个产生元素,可以节省内存。
一、迭代器
- 迭代器类
满足以下三个条件的类被称为:迭代器类
1.类中定义了__iter__和__next__两个方法
2.__iter__方法要返回对象本身,即:self
3.__next__方法,返回下一个数据,如没有数据了,则抛出StopIteration异常
官方文档:https://docs.python.org/3/library/stdtypes.html#iterator-types
- 迭代器对象
通过类的实例化创建迭代器对象
二、生成器
生成器完全符合迭代器的规则,生成器是一种特殊的迭代器。
- 生成器类
python中内置的generator类,该类内部也定义了__iter__和__next__两个方法
- 生成器对象
生成器对象通过 生成器推导式 或 生成器函数() 来创建
- 创建方式1:生成器推导式
# 生成器推导式,类似于列表推导式,只是把[]换成()
my_generator = (i * 2 for i in range(5))
print(type(my_generator)) # 打印结果:<class 'generator'>
# 列表推导式
my_list = [i * 2 for i in range(5)]
print(type(my_list)) # 打印结果:<class 'list'>
- 创建方式2:生成器函数(yield关键字)
只要定义的函数中出现了yield,则该函数称为:生成器函数
调用生成器函数不会执行函数体,会返回一个生成器对象
yield关键字类似于return,代码执行到yield会暂停,再次启动生成器时会在继续往下执行
def my_generator(n):
for i in range(n):
yield i
# 调用函数返回生成器对象
gen = my_generator(10)
print(next(gen)) # 打印结果:0
print(next(gen)) # 打印结果:1
for i in gen: # 打印结果:2,3,4
print(i)
生成器举例(斐波那契数列):
def fb(num):
a = 0
b = 1
index = 0
while index < num:
result = a
a, b = b, a + b
yield result
index += 1
f = fb(5)
for i in f:
print(i)
三、可迭代对象
一个类中定义了 __iter__ 方法,且该方法返回一个迭代器对象(生成器对象):则称这个类创建的对象为“可迭代对象”
# 常见的可迭代对象
iterables = [
"123", # 字符串
[1, 2, 3], # 列表
(1, 2, 3), # 元组
{1, 2, 3}, # 集合
{1: "a", 2: "b"} # 字典
]
四、for循环内部执行流程
for循环后面跟的必须是“可迭代对象”,即for item in 可迭代对象,内部执行流程如下:
- 执行 “可迭代对象” 的__iter__() 方法,返回“迭代器对象”
- 循环执行 “迭代器对象” 的__next__() 方法,直至捕获StopIteration异常,遍历结束
五、判断可迭代对象、迭代器对象
使用isinstance方法可以判断对象是否为“可迭代对象”,判断依据:是否有__iter__()方法
from collections.abc import Iterable
mylist = [2,3,5]
print(isinstance(mylist,Iterable)) # 返回True
使用isinstance()函数可以判断对象是否为“迭代器对象”,判断依据:是否有__iter__()和__next__()方法
from collections.abc import Iterator
mylist = [2,3,5]
print(isinstance(mylist,Iterator)) # 返回False
六、python内置函数iter()与next() `
- iter(可迭代对象),返回“可迭代对象”的“迭代器对象”(等价于执行 可迭代对象.__iter__() )
- next(迭代器对象),返回“可迭代对象”的值 (等价于执行 迭代器对象.__next__() )
七、python内置函数enumerate()
enumerate()函数中传入可迭代对象,返回enumerate(枚举)对象,同时列出了数据和数据下标
enumerate(枚举)对象也是可迭代对象
mylist = [2,3,5]
for index,val in enumerate(mylist):
print(index,val)