迭代器:可以被next()函数调用并不断返回下一个值的对象
生成器:是一种特殊的迭代器,可以用yield语句来返回值,每次调用next()函数,
都会执行yield语句直到遇到下一个yield语句,然后返回yield语句后面的值
迭代器和生成器的区别:
迭代器一次性返回所有值,而生成器返回一个值,需要多次调用next()函数才能返回下一个值
迭代器只能遍历一次,而生成器可以多次遍历
迭代器占用内存小,生成器占用内存大
迭代器只能用于一次性遍历,而生成器可以用于迭代和生成值
迭代器可以用for循环,而生成器只能用next()函数
迭代器可以用list()函数转换为列表,而生成器只能用list()函数一次性转换为列表
迭代器可以用next()函数获取下一个值,而生成器只能用send()函数发送值给生成器,
然后生成器会返回yield语句后面的值
1、迭代器
在Python中,迭代器是一个可以记住遍历位置的对象。它从集合的第一个元素开始访问,直到所有的元素被访问结束。迭代器只能往前不会后退。要创建一个迭代器,你需要实现两个方法:__iter__()和__next__()。__iter__()方法返回迭代器对象本身,而__next__()方法返回下一个元素。如果不再有元素可返回,__next__()方法会引发一个StopIteration异常。
-
__iter__():返回自身。 -
__next__():返回下一个元素;如果没有更多元素,则抛出StopIteration异常。
1.1 特点
-
惰性计算:按需生成数据,节省内存。
-
实现协议:
-
__iter__():返回自身。 -
__next__():返回下一个元素;如果没有更多元素,则抛出StopIteration异常。
-
-
可迭代对象(Iterable)与迭代器不同:
-
可迭代对象实现
__iter__()方法,返回一个迭代器。 -
迭代器既实现
__iter__()又实现__next__()。
-
1.2 迭代器的创建
-
迭代器只能往前取值,不会后退
-
用iter函数可以返回一个可迭代对象的迭代器
# 示例 可迭代对象
L = [1, 3, 5, 7]
it = iter(L) # 从L对象中获取迭代器
next(it) # 1 从迭代器中提取一个数据
next(it) # 3
print(next(it)) # 5
next(it) # 7
# 示例2 生成器函数
It = iter(range(1, 10, 3))
next(It) # 1
print(next(It)) # 4
next(It) # 7
1.3自定义
# 自定义迭代器类
class MyIterator:
def __init__(self, data):
self.data = data
self.index = 0
def __iter__(self):
return self # 迭代器返回自身
def __next__(self):
if self.index < len(self.data):
result = self.data[self.index]
self.index += 1
return result
else:
raise StopIteration # 数据迭代结束
# 使用自定义迭代器
my_iter = MyIterator([1, 2, 3])
for item in my_iter:
print(item)
2、生成器
Generator
生成器是一种特殊的迭代器,通过函数定义,用 yield 语句生成值。生成器可以自动实现迭代协议,无需手动实现 __iter__() 和 __next__()。
2.1 特点
-
简洁:比手动实现迭代器更易写。
-
惰性计算:生成器在每次调用 next() 时生成一个值,而不是一次性生成所有值。
-
yield:暂停函数执行并返回值,保留函数的状态,以便下一次继续执行。
示例代码:
# 生成器函数
def my_generator():
print("Start")
yield 1
print("Continue")
yield 2
print("End")
yield 3
# 使用生成器
gen = my_generator()
for val in gen:
print(val)
2.2 生成器表达式
生成器可以用表达式形式定义,类似列表推导式,但使用小括号 ()。
语法
(表达式 for 变量 in 可迭代对象 [if 真值表达式])
# 生成器表达式
gen_expr = (x**2 for x in range(5))
print(next(gen_expr)) # 0
print(next(gen_expr)) # 1
2.3应用场景
-
数据流处理:处理大文件或流式数据,避免内存耗尽。
-
无限序列生成:如斐波那契数列、素数序列。
-
管道化数据处理:与
itertools模块结合使用。
def read_large_file(file_path):
with open(file_path, 'r') as file:
for line in file:
yield line.strip()
for line in read_large_file('large_file.txt'):
print(line)
3、 区别对比
| 特性 | 迭代器 | 生成器 |
|---|---|---|
| 实现 | 通过类实现,手动定义方法 | 使用函数和 yield 定义,自动实现迭代协议 |
| 代码简洁性 | 代码较复杂 | 代码简单 |
| 状态管理 | 手动管理状态 | 自动保存函数的运行状态 |
| 惰性计算 | 支持 | 支持 |
| 示例应用 | 自定义复杂的迭代逻辑 | 简单的数据流生成 |
1652

被折叠的 条评论
为什么被折叠?



