可迭代对象
迭代器类
一个迭代器类必须实现以下两个方法:
__iter__():返回迭代器对象本身(即self)。__next__():返回序列中的下一个元素。如果没有更多元素,抛出StopIteration异常。
class MyRange:
def __init__(self, start, end):
self.start = start
self.end = end
def __iter__(self):
return self
def __next__(self):
if self.start < self.end:
current = self.start
self.start += 1
return current
else:
raise StopIteration
迭代器对象
顾名思义就是迭代器类的实例,还是上面的迭代器类举例
Python 内置函数 next() 可以传入一个迭代器对象,会自动调用 __next()__ 函数
my_range = MyRange(1, 10) # my_range 就是一个迭代器对象
print(next(my_range)) # 输出1
print(next(my_range)) # 输出2
print(next(my_range)) # 输出3
可迭代对象
必须有 __iter__() 方法,这个方法返回一个迭代器对象
class MyRange: # 迭代器类
def __init__(self, start, end):
self.start = start
self.end = end
def __iter__(self):
return self
def __next__(self):
if self.start < self.end:
current = self.start
self.start += 1
return current
else:
raise StopIteration
class MyRange2:
def __iter__(self):
return MyRange(0, 5) # 返回一个迭代器对象
for x in MyRange2(): # MyRang2() 就是一个可迭代对象
print(x)
for 循环本质
- 获取迭代器对象(如果是可迭代对象,就先获取其迭代器对象)
- 反复调用
next()函数,内部会调__next()__方法获取下一个元素 - 捕获 StopIteration 异常,跳出循环
for x in MyRange(5, 10):
print(x) # 输出 5,6,7,8,9
生成器对象
- 函数里面有
yield就是生成器对象(yield把函数变成了一个生成器对象) - 调用该函数不会立即执行其中代码,而是返回一个生成器对象
- 当作为参数传入
next()时:每次会从上次暂停的地方继续执行函数,直到遇到yield,返回值并再次暂停
from collections.abc import Iterable
def gen_fun():
yield 1 # 第一次调用 next() 返回1 并暂停
yield 2 # 第二次调用 next() 返回2 并暂停
print("hello world")
yield 3 # 第三次调用 next() 输出 hello world 并返回3,然后暂停
gen = gen_fun()
print(isinstance(gen, Iterable)) # 输出 True。gen 是否是可迭代对象
print(hasattr(gen, '__iter__')) # 输出 True。gen 是否具有 __iter__ 方法
print(hasattr(gen, '__next__')) # 输出 True。gen 是否具有 __next__ 方法
print(next(gen)) # 输出 1
print(next(gen)) # 输出 2
print(next(gen)) # 输出3(会先打印 hello world)
print(next(gen)) # 报错。函数已经执行完了(没有下一个元素了),因为也是迭代器对象,所以会抛出 StopIteration
生成器应用1
def read_large_file(file_path):
with open(file_path, 'r') as file:
for line in file:
yield line.strip() # strip() 去除前后的空格
# 逐行读取大文件
file_gen = read_large_file('large_file.txt')
for line in file_gen:
print(line)
生成器应用2
def gen_function():
i = 2
yield i # 质数从 2 开始
while True:
i += 1
for j in range(2, i): # 循环 2 - i(比如当前是 4,需要判断2到4之间的数是否能被 4 整除)
if (i % j) == 0: # 如果能整除说明不是质数,就跳出循环
break
else: # 没有 break 才会走这里,没 break 说明之间的数都不能整除,当前值就是质数
yield i
if __name__ == '__main__':
gen = gen_function()
for i in range(20): # 连续生成 20 个质数
print(next(gen))
总结
- 迭代器对象有
__iter__()、__next__()两个方法 - 可迭代对象只有
__iter__()一个方法 - 迭代器对象也是可迭代对象,反之不成立
- 元组、列表、字典、字符串 都是可迭代对象
- 生成器对象是惰性计算,每次调用才返回下一个对象,所以比较节省内存,也是可迭代对象

浙公网安备 33010602011771号