生成器 #

生成器是一种惰性计算的迭代器,使用yield关键字生成值。

一、基本语法 #

python
def my_generator():
    yield 1
    yield 2
    yield 3

gen = my_generator()
print(next(gen))  # 1
print(next(gen))  # 2
print(next(gen))  # 3
# print(next(gen))  # StopIteration

# 使用for循环
for value in my_generator():
    print(value)

二、生成器表达式 #

python
# 生成器表达式
gen = (x ** 2 for x in range(5))
print(list(gen))  # [0, 1, 4, 9, 16]

# 对比列表推导式
lst = [x ** 2 for x in range(5)]  # 立即计算

# 生成器惰性计算,节省内存
gen = (x ** 2 for x in range(1000000))  # 几乎不占内存

三、yield的工作原理 #

python
def count_up_to(n):
    count = 1
    while count <= n:
        yield count  # 暂停并返回值
        count += 1   # 下次从这里继续

for num in count_up_to(5):
    print(num)  # 1 2 3 4 5

四、生成器方法 #

4.1 send方法 #

python
def accumulator():
    total = 0
    while True:
        value = yield total
        if value is not None:
            total += value

gen = accumulator()
print(next(gen))      # 0(初始化)
print(gen.send(10))   # 10
print(gen.send(5))    # 15

4.2 throw方法 #

python
def my_gen():
    try:
        yield 1
        yield 2
    except ValueError:
        yield "捕获异常"

gen = my_gen()
print(next(gen))        # 1
print(gen.throw(ValueError))  # "捕获异常"

4.3 close方法 #

python
def my_gen():
    try:
        yield 1
        yield 2
    finally:
        print("清理资源")

gen = my_gen()
print(next(gen))  # 1
gen.close()       # 清理资源

五、实际应用 #

5.1 读取大文件 #

python
def read_large_file(filename):
    with open(filename) as f:
        for line in f:
            yield line.strip()

for line in read_large_file("large.txt"):
    process(line)

5.2 无限序列 #

python
def infinite_counter():
    n = 0
    while True:
        yield n
        n += 1

counter = infinite_counter()
print(next(counter))  # 0
print(next(counter))  # 1
print(next(counter))  # 2

5.3 斐波那契数列 #

python
def fibonacci():
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a + b

fib = fibonacci()
for _ in range(10):
    print(next(fib))  # 0 1 1 2 3 5 8 13 21 34

5.4 数据管道 #

python
def read_lines(filename):
    with open(filename) as f:
        for line in f:
            yield line

def filter_comments(lines):
    for line in lines:
        if not line.strip().startswith('#'):
            yield line

def strip_lines(lines):
    for line in lines:
        yield line.strip()

# 管道处理
pipeline = strip_lines(filter_comments(read_lines("file.txt")))
for line in pipeline:
    print(line)

六、yield from #

python
def sub_gen():
    yield 1
    yield 2

def main_gen():
    yield from sub_gen()  # 委托给子生成器
    yield 3

for value in main_gen():
    print(value)  # 1 2 3

七、生成器vs列表 #

python
# 列表:立即创建,占用内存
numbers_list = [x ** 2 for x in range(1000000)]

# 生成器:惰性计算,节省内存
numbers_gen = (x ** 2 for x in range(1000000))

# 生成器只能迭代一次
gen = (x for x in range(3))
print(list(gen))  # [0, 1, 2]
print(list(gen))  # [](已经迭代完)

八、总结 #

特点 说明
关键字 yield
惰性计算 按需生成
内存效率 节省内存
单次迭代 只能迭代一次
表达式 (x for x in iter)
最后更新:2026-03-16