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

Python中直接赋值与copy.copy()的差异疑问——基于链表代码实践

关于Python中=赋值与copy.copy()在链表操作中的差异问题

我是Python新手,此前了解到Python中的=属于浅拷贝操作,因此认为代码中的语句this_out = this_out.next与this_out = copy.copy(this_out.next)的执行效果应当一致,但实际运行后输出结果却不相同。相关代码如下,想请教这一现象产生的原因:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:
        length_1 = 0
        tmp_1 = l1
        l1_true_val = 0
        l1_end = False

        length_2 = 0
        tmp_2 = l2
        l2_true_val = 0
        l2_end = False

        while(1):
            if l1_end is False:
                l1_true_val = l1_true_val + tmp_1.val * pow(10, length_1)
                if tmp_1.next is not None:
                    tmp_1 = tmp_1.next
                    length_1 = length_1 + 1
                else:
                    l1_end = True
            if l2_end is False:
                l2_true_val = l2_true_val + tmp_2.val * pow(10, length_2)
                if tmp_2.next is not None:
                    tmp_2 = tmp_2.next
                    length_2 = length_2 + 1
                else:
                    l2_end = True
            if l1_end is True and l2_end is True:
                break
        output = l1_true_val + l2_true_val

        devider = 10
        if output == 0:
            Out = ListNode(val=0)
            return Out

        Out = ListNode()
        this_out = Out

        while(output):
            this_out.val = output % 10
            output = output // 10
            if output != 0:
                nxt_out = ListNode()
                this_out.next = nxt_out
                this_out = this_out.next
                #this_out = copy.copy(this_out.next)

        return Out            

我参考了Python官方copy模块文档,但仍有此疑问。


问题解答

首先纠正一个核心误解:Python里的=不是拷贝操作,它只是给内存中的同一个对象绑定了一个新的变量名——简单说就是让两个变量指向同一个东西,完全没有创建新对象。

而copy.copy()是真正的浅拷贝:它会创建一个新的对象,把原对象的表层属性值复制过来,但新对象和原对象是内存中独立的两个实体。

回到你的链表代码,两者的差异直接导致逻辑错误:

  • 当执行this_out = this_out.next时,this_out直接指向了this_out.next原本指向的那个ListNode对象。后续你对this_out的操作(比如给val赋值),都是直接修改这个已经存在的节点,而这个节点已经通过this_out.next = nxt_out挂在了链表链上,链表的结构会正常维持。
  • 但如果换成this_out = copy.copy(this_out.next),你复制出了一个和this_out.next内容相同的新ListNode对象,此时this_out指向的是这个新节点,而原来的this_out.next还是指向旧节点。这就意味着新节点根本没有被加入到原来的链表链中,后续你对这个新节点的操作不会影响返回的Out链表,最终返回的链表只会包含第一个节点,后面的节点都断链了,输出结果自然不对。

举个直白的例子:假设当前this_out指向节点A,A.next是节点B。

  • 用this_out = A.next:this_out现在指向B,后续修改this_out.val就是修改B的属性,链表保持A→B→...的正常链接。
  • 用this_out = copy.copy(A.next):this_out指向B的拷贝B',但A的next属性依然指向B,B'不在链表链里,最后返回的链表只有A→B,你操作的B'根本没被加入进去,结果必然出错。

总结:=是变量指向复用,copy.copy()是创建新对象,两者本质完全不同,在链表这种依赖对象引用链的场景中,差异会直接导致逻辑失效。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 16:10:32