IF语句短路判断异常:list2为None时仍触发val属性访问报错
合并两个单链表的条件判断错误修复
问题场景
实现mergeTwoLists函数合并两个单链表时,遇到条件判断逻辑问题:当其中一个链表为空时,条件语句仍会尝试访问空链表节点的val属性,抛出AttributeError错误。具体表现为:list2为空时,尽管not list2结果为True,程序仍会执行后续的list2.val访问操作;同理list1为空时也会触发类似错误。
问题代码
# Definition for singly-linked list. # class ListNode(object): # def __init__(self, val=0, next=None): # self.val = val # self.next = next class Solution(object): def mergeTwoLists(self, list1, list2): """ :type list1: Optional[ListNode] :type list2: Optional[ListNode] :rtype: Optional[ListNode] """ res = ListNode(0) curr = res while list1 or list2: if not list2 or list1.val <= list2.val: curr.next = ListNode(list1.val) list1 = list1.next if list1 else None elif not list1 or list2.val < list1.val: curr.next = ListNode(list2.val) list2 = list2.next if list2 else None curr = curr.next if curr else None return res.next
报错信息
AttributeError: 'NoneType' object has no attribute 'val' if not list2 or list1.val <= list2.val: Line 17 in mergeTwoLists (Solution.py) ret = Solution().mergeTwoLists(param_1, param_2) Line 48 in _driver (Solution.py) _driver() Line 58 in <module> (Solution.py)
问题原因
原条件判断未利用Python逻辑运算符的短路求值特性,且判断顺序错误:
- 当
list1为空时,not list2为False,程序会执行list1.val的访问操作,触发错误 - 当
list2为空时,若list1也为空,while循环本应终止,但原代码的条件组合仍存在风险
修复方案
调整条件判断顺序,先处理其中一个链表为空的场景,再对非空链表的值进行比较,利用短路求值避免访问None对象的属性:
# Definition for singly-linked list. # class ListNode(object): # def __init__(self, val=0, next=None): # self.val = val # self.next = next class Solution(object): def mergeTwoLists(self, list1, list2): """ :type list1: Optional[ListNode] :type list2: Optional[ListNode] :rtype: Optional[ListNode] """ res = ListNode(0) curr = res while list1 or list2: # 若list1为空,直接取list2的节点 if not list1: curr.next = ListNode(list2.val) list2 = list2.next # 若list2为空,直接取list1的节点 elif not list2: curr.next = ListNode(list1.val) list1 = list1.next # 两者都非空时,取值较小的节点 elif list1.val <= list2.val: curr.next = ListNode(list1.val) list1 = list1.next else: curr.next = ListNode(list2.val) list2 = list2.next curr = curr.next return res.next
也可以简化为更紧凑的条件写法,同样利用短路求值:
while list1 or list2: if list1 and (not list2 or list1.val <= list2.val): curr.next = ListNode(list1.val) list1 = list1.next else: curr.next = ListNode(list2.val) list2 = list2.next curr = curr.next
说明
拆分条件后,程序会优先处理链表为空的边界场景,确保只有当链表非空时才会访问其val属性,彻底避免NoneType属性访问错误。
内容的提问来源于stack exchange,提问作者Alexandre Bernard
相关产品推荐
相关产品推荐

