You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

类属性按引用还是值赋值?结合LeetCode合并链表实例答疑

合并两个有序链表的变量赋值疑问

LeetCode 合并两个有序链表解决方案

class Solution(object):
    def mergeTwoLists(self, list1, list2):
        """
        :type list1: Optional[ListNode]
        :type list2: Optional[ListNode]
        :rtype: Optional[ListNode]
        """
        
        prehead = ListNode(-1)
        curr = prehead

        while list1 and list2:
            if (list1.val <= list2.val):
                curr.next = list1
                list1 = list1.next
            else:
                curr.next = list2
                list2 = list2.next
            curr = curr.next
        
        curr.next = list1 if list1 != None else list2

        return prehead.next

疑问与示例

当执行curr.next = list1后立刻执行list1 = list1.next时,为何curr.next没有指向list1.next?我认为这些对象及其属性是可变的,即变量赋值指向内存地址。

为确认我对变量赋值的理解是否正确,请看以下示例:

a = []
b = [1]
a = b
b.append(2)

print(a)
print(b)

print(id(a))
print(id(b))

在此示例中,修改b后a与b仍相等,上述链表示例与该列表示例有何不同?


核心差异解析

链表示例里的操作分两步:

  1. curr.next = list1:将curr对象的next属性,指向当前list1变量引用的那个ListNode对象(暂称NodeA)。
  2. list1 = list1.next:这是给list1变量重新赋值,让它指向NodeA的next属性对应的对象(NodeB)。但这步只改变了list1变量的指向,完全不会影响curr.next——因为curr.next已经固定指向NodeA了,和list1现在指向谁没关系。

列表示例的操作逻辑不同:

  1. a = b:让a和b两个变量同时指向同一个列表对象(暂称ListX)。
  2. b.append(2):这是直接修改ListX这个对象本身的内容,而非改变b变量的指向。因为a和b始终指向ListX,所以修改对象后,两个变量访问到的都是修改后的ListX,结果自然一致。

一句话总结:

  • 链表示例改的是变量的指向,没碰对象本身,所以curr.next不受影响;
  • 列表示例改的是变量指向的对象的内容,变量指向没变,所以两个变量的结果同步。

内容的提问来源于stack exchange,提问作者user23357772

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 19:37:03