Python 3.10生成器表达式异常处理:如何解决StopIteration运行时错误?
解决
RuntimeError: generator raised StopIteration错误 你遇到的问题源于Python版本兼容性:Python 3.7及以后版本明确规定,生成器中直接抛出StopIteration会触发RuntimeError。原代码里的生成器表达式tuple(next(items) for i in range(n))在迭代器耗尽时,next()会抛出该异常且无法被捕获,导致报错。
以下是两种可行的修复方案:
方案一:手动捕获异常构建分组
显式循环并捕获StopIteration,逐个收集元素直到迭代器耗尽或凑足指定数量:
from typing import Iterator, Tuple def group_by_iter(n: int, items: Iterator) -> Iterator[Tuple]: """ >>> list( group_by_iter( 7, filter( lambda x: x%3==0 or x%5==0, range(1,50) ) ) ) [(3, 5, 6, 9, 10, 12, 15), (18, 20, 21, 24, 25, 27, 30), (33, 35, 36, 39, 40, 42, 45), (48,)] """ while True: row = [] for _ in range(n): try: row.append(next(items)) except StopIteration: break if not row: break yield tuple(row) print( list( group_by_iter( 7, filter( lambda x: x%3==0 or x%5==0, range(1,50) ) ) ) )
方案二:使用itertools.islice简化实现
itertools.islice可安全地从迭代器中截取指定数量的元素,迭代器耗尽时自动返回空序列,无需手动处理异常,更符合函数式编程风格:
from itertools import islice from typing import Iterator, Tuple def group_by_iter(n: int, items: Iterator) -> Iterator[Tuple]: """ >>> list( group_by_iter( 7, filter( lambda x: x%3==0 or x%5==0, range(1,50) ) ) ) [(3, 5, 6, 9, 10, 12, 15), (18, 20, 21, 24, 25, 27, 30), (33, 35, 36, 39, 40, 42, 45), (48,)] """ while True: row = tuple(islice(items, n)) if not row: break yield row print( list( group_by_iter( 7, filter( lambda x: x%3==0 or x%5==0, range(1,50) ) ) ) )
两种方案均能输出预期结果,运行后可得到示例中的分组列表。
内容的提问来源于stack exchange,提问作者muc
相关产品推荐
相关产品推荐

