题目重点:用iter/next协议区分可重复集合与消费状态,解释StopIteration和测试边界。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 训练同步迭代协议;序列旧式迭代适配不作为核心实现要求。
解题路线
- 可迭代对象能够通过iter获得迭代器;迭代器通过next逐项返回,并在耗尽时抛StopIteration。迭代器的iter通常返回自身,保存当前消费位置。
- list作为可迭代容器,每次iter(list)可产生独立游标;生成器既是可迭代对象也是自己的迭代器,不会每次for自动重新启动。
- for语句本质获取一个迭代器再反复next直到耗尽。自定义类需明确是容器返回新迭代器,还是对象本身持单游标;混用易造成嵌套遍历互相干扰。
- __next__中返回None表示产出一个合法None值,不是结束;结束必须抛StopIteration。遍历期间修改容器的语义由具体对象定义,不应统一承诺不会出错。
- 迭代器抽象不意味着内部操作O(1),数据库游标next可能网络IO或分页加载。测试应模拟慢页、异常、空页与消费者取消,不能只用小list替代真实生命周期。
- 公共API可要求Iterable并只遍历一次,避免先len/索引再遍历限制流式输入;若确实要多遍,需要明确缓存或要求可重复的数据源。
手动走一遍
items=[1,2],iter(items)两次得到独立游标;对g生成器,iter(g) is g。next会推进g,耗尽后不能靠iter(g)恢复。返回None仍是元素,异常StopIteration才结束。
规模与取舍
协议本身没有通用每步复杂度;简单序列游标额外O(1)状态,完整消费成本是各next成本之和。多遍缓存会增加O(n)存储。
易错点与追问
容易失分的边界
- None当耗尽信号。
- 所有Iterable都可重复使用。
- next总是常量无IO。
继续深挖
- 怎样支持独立嵌套遍历?
- 有异常的游标如何清理?
- 只允许一次读取的输入怎样测?
技术参考
- Python Built-in Types:技术语义参考,具体题目按本文约定。
