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
相关产品推荐
相关产品推荐

