Python链表两数相加传参报list object无val属性错误
报错产生原因
- 核心原因是类型不匹配:
addTwoNumbers方法的入参要求是ListNode类的实例(也就是链表的头节点),这类实例才有val(节点值)、next(下一个节点指针)属性,但你第一次测试直接传入了Python原生列表[1,2,3]、[4,5,6],原生list类型没有定义这两个属性,访问时直接触发报错。 - 你后续调整的代码存在3个逻辑问题:
insert_at_end方法设计为插入单个数值的节点,但调用时直接传入了整个列表,会把整个列表对象作为单个节点的val存储,根本没有生成符合要求的、每个节点存单个数字的链表结构。- 给
Solution类新增的head属性、插入/打印链表的方法属于数据构造逻辑,和解题的两数相加逻辑耦合在一起,不符合类的职责划分,也没有实际调用addTwoNumbers方法执行计算。 - 初始版本的
ListNode类构造方法存在缩进错误,self.val和self.next没有缩进在__init__方法块内,运行时也会触发语法错误(你调整后的版本已经修复了这个问题)。
修复方案
- 拆分职责:
Solution类只保留解题的addTwoNumbers方法,不要把链表数据存在Solution实例上。 - 单独写通用的类型转换方法,把测试用的Python原生列表转换成
ListNode结构的链表,计算完成后再把结果链表转回普通列表方便查看输出。 - 测试时先做类型转换,再传入计算方法,不要直接传原生列表。
修复后的可运行完整代码如下:
# 单链表节点定义 class ListNode: def __init__(self, val=0, next=None): self.val = val self.next = next class Solution: def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode: dummy = ListNode() cur = dummy carry = 0 while l1 or l2 or carry: v1 = l1.val if l1 else 0 v2 = l2.val if l2 else 0 # 计算当前位总和与进位 total = v1 + v2 + carry carry = total // 10 cur.next = ListNode(total % 10) # 移动所有指针 cur = cur.next l1 = l1.next if l1 else None l2 = l2.next if l2 else None return dummy.next # 工具函数:Python列表转链表,返回链表头节点 def list_to_linked_list(num_list): dummy = ListNode() cur = dummy for num in num_list: cur.next = ListNode(num) cur = cur.next return dummy.next # 工具函数:链表转Python列表,方便打印结果 def linked_list_to_list(head): res = [] while head: res.append(head.val) head = head.next return res # 测试逻辑 if __name__ == "__main__": # 测试用例:l1对应342(逆序存储:2->4->3),l2对应465(逆序存储:5->6->4) l1 = list_to_linked_list([2,4,3]) l2 = list_to_linked_list([5,6,4]) sol = Solution() result = sol.addTwoNumbers(l1, l2) print(linked_list_to_list(result)) # 输出[7,0,8],对应结果807,计算正确
如果你想沿用自己写的insert_at_end方法,需要把方法逻辑改成支持遍历列表逐个插入节点,并且不要把链表挂载到Solution类上,单独封装链表类即可,核心原则是传入addTwoNumbers的必须是ListNode实例,不能直接传原生列表。
内容的提问来源于stack exchange,提问作者Andy
相关产品推荐
相关产品推荐

