不会崩溃。itertools.chain.from_iterable对空迭代器完全友好,真正出问题的是外层迭代器中混入None、不可迭代对象或抛异常的生成器。
不会崩溃。itertools.chain.from_iterable 本身对空迭代器完全友好——它接受一个可迭代对象(比如空列表、空生成器),只要这个对象本身可迭代,就不会报错。真正出问题的,往往是传入的“外层”迭代器里混入了 None、不可迭代对象(如 int)、或抛出异常的生成器。
常见误判“空”的场景:
[None, [1, 2], []]:None 不可迭代,from_iterable 在尝试 for x in None 时抛 TypeError: 'NoneType' object is not iterable
[[], 0, [3]]:整数 0 不可迭代,同上错误yield 出 None:from_iterable 迭代到那一项时立即失败(x for x in []))):完全安全,不执行任何 yield,返回空迭代器最直接的办法是在调用前过滤或转换可疑项。不需要引入额外依赖,用生成器表达式即可:
from itertools import chain
def safe_from_iterable(iterables):
return chain.from_iterable(
x for x in iterables if hasattr(x, '__iter__') and not isinstance(x, (str, bytes))
)
说明:
hasattr(x, '__iter__') 粗筛可迭代性(覆盖 list/tuple/generator 等)str 和 bytes:避免把字符串当序列展开成单个字符(通常不是预期行为)collections.abc.Iterable 判断更准确None 并跳过,可加 and x is not None
不推荐。因为 from_iterable 是惰性求值的——错误只在你真正消费结果时才抛出(比如 list() 或 for 循环中)。这意味着:
预处理比事后兜底更可控,尤其在数据来源不可信(如用户输入、API 响应)时。
真正容易被忽略的是:空迭代器本身从不导致问题,问题永远出在“你以为它空,其实它藏了个 None 或数字”。检查外层容器的内容类型,比检查长
