要让自定义链表支持 for 遍历,需实现 iter__(返回迭代器对象,可为 self 或独立迭代器)和 __next__(管理状态并抛出 stopiteration),或更推荐用生成器函数实现 __iter 以自动处理迭代逻辑。

要让自定义链表支持 for item in my_list 这样的遍历,关键不是“写个循环”,而是让链表成为 Python 认可的可迭代对象——这需要正确实现 __iter__ 和 __next__ 两个魔术方法。
必须实现 __iter__ 方法
这个方法告诉 Python:“我是一个可迭代对象”。它不能返回数据本身,而必须返回一个迭代器对象。最常用、最简洁的做法是返回 self(即链表实例自己),前提是该实例也实现了 __next__:
- 如果选择返回 self,就必须在链表类中同时定义
__next__,并维护遍历状态(比如当前节点引用和计数) - 也可以返回一个独立的迭代器类实例(更清晰分离关注点,适合复杂逻辑)
- 不能返回列表或生成器表达式(如
return [node.data for node in self]),那样就失去了链表“按需逐个取值”的意义,也违背了迭代器的惰性求值原则
__next__ 方法要管理遍历状态
这个方法每次被调用时,负责返回下一个元素,并推进内部状态。常见实现方式有:
- 用一个指针(如
self._current)从头节点开始,每次调用就移动到next节点 - 用一个索引(如
self._index)配合get(index)方法获取节点,但效率低(每次get都要从头遍历) - 遇到末尾(比如到达尾哨兵或
None)时,必须显式抛出StopIteration异常,这是 for 循环停止的唯一信号
注意可迭代对象与迭代器的区别
这是最容易混淆的地方:
-
链表本身是可迭代对象(实现了
__iter__) - 每次调用 iter(my_list) 得到的是一个迭代器(有状态、一次性的)
- 同一个链表可以同时存在多个独立迭代器,互不干扰;但一个迭代器遍历完后再次调用
next()会持续抛出StopIteration - 不要在
__iter__中重置状态(如把self._current = self._head),否则会导致多个 for 循环互相影响
推荐用生成器简化实现
比起手动管理状态和异常,更 Pythonic 的做法是把 __iter__ 写成生成器函数(使用 yield)。它天然具备迭代器行为,无需写 __next__:
- 在
__iter__中遍历节点,对每个有效节点yield node.data(或yield node) - 生成器自动处理
StopIteration和状态保存,代码更短、更安全 - 例如:
def __iter__(self): curr = self._head.next; while curr != self._tail: yield curr.data; curr = curr.next











