
本文详解如何为双向链表类正确实现 __str__ 方法,避免返回内存地址,而是以 [val1->val2->val3] 格式清晰输出节点数据,并提供可运行示例与关键注意事项。
本文详解如何为双向链表类正确实现 `__str__` 方法,避免返回内存地址,而是以 `[val1->val2->val3]` 格式清晰输出节点数据,并提供可运行示例与关键注意事项。
在 Python 中实现双向链表时,一个常见误区是将 __str__ 方法错误地定义在 Node 类中,或在遍历时未正确访问链表头节点(self.head),导致 AttributeError 或打印出对象内存地址(如 <__main__.node object at></__main__.node>)。正确的做法是:将 __str__ 定义在链表容器类(如 DoublyLinkedList)中,由它统一管理遍历逻辑和格式化输出。
以下是一个完整、可直接运行的实现示例:
class Node:
def __init__(self, data, prev=None, next=None):
self.data = data
self.prev = prev
self.next = next
class DoublyLinkedList:
def __init__(self):
self.head = None # 链表起始节点(无哨兵节点)
def append(self, data):
"""尾部插入新节点"""
new_node = Node(data)
if not self.head:
self.head = new_node
else:
current = self.head
while current.next:
current = current.next
current.next = new_node
new_node.prev = current
def __str__(self):
"""返回形如 [a->b->c] 的字符串表示"""
values = []
current = self.head
while current is not None:
values.append(str(current.data)) # 统一转为字符串,支持 int/str/float 等类型
current = current.next
return "[" + "->".join(values) + "]"
# 可选:支持反向遍历(验证双向性)
def to_list_reverse(self):
if not self.head:
return []
# 找到尾节点
tail = self.head
while tail.next:
tail = tail.next
# 从尾向前遍历
result = []
current = tail
while current:
result.append(current.data)
current = current.prev
return result✅ 使用示例:
dll = DoublyLinkedList()
dll.append(10)
dll.append("hello")
dll.append(3.14)
print(dll) # 输出:[10->hello->3.14]
print(dll.to_list_reverse()) # 输出:[3.14, 'hello', 10]⚠️ 关键注意事项:
-
不要把
__str__放在Node类里:单个节点无法代表整个链表结构,且self._head在Node实例中并不存在(会报AttributeError)。 -
避免空指针访问:遍历前务必检查
current is not None,尤其在head为空时(如刚初始化的链表)。 -
数据类型兼容性:
str(current.data)能安全处理任意可字符串化的类型(int,str,bool, 自定义类等),无需提前假设类型。 -
性能提示:使用
list.append()+'->'.join()比字符串拼接(s += ...)更高效,尤其对长链表;Python 的join底层为 C 实现,时间复杂度 O(n),而反复字符串拼接为 O(n²)。
? 进阶建议:
若需支持正向/反向双端打印(如 [abc]),可在 __str__ 中改用双向遍历逻辑;若追求更高可读性,还可重写 __repr__ 返回调试友好格式(如 DoublyLinkedList([10, 'hello', 3.14]))。
通过以上实现,你将获得一个健壮、清晰、符合 Python 惯例的双向链表字符串表示机制。


















