Python 多变量赋值的机制(以反转链表为例)

Python 多变量赋值的机制

在刷LeeCode反转链表这道题时(输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL),遇到了一个很有意思的问题。

以下是解答区给出的实现方法,采用多变量同时赋值

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    def reverseList(self, head: ListNode) -> ListNode:
        cur, pre = head, None
                while cur:
            cur.next, pre, cur = pre, cur, cur.next  ###  ---1
        return pre

但是当稍微改变一下—1这一行赋值语句的顺序,如修改为 pre, cur, cur.next = cur, cur.next, pre 则会报错。为了搞清楚这其中的曲折,我们先来了解一下python中多变量赋值的机制。

Python自带了一个字节码工具叫dis,通过dis我们可以看到多变量赋值的真相。
import dis

def foo():
    t=1
    t,a=3,t+1
dis.dis(foo)

输出的如下

 21           0 LOAD_CONST               1 (1)
              2 STORE_FAST               0 (t)

 22           4 LOAD_CONST               2 (3)
              6 LOAD_FAST                0 (t)
              8 LOAD_CONST               1 (1)
             10 BINARY_ADD
             12 ROT_TWO
             14 STORE_FAST               0 (t)
             16 STORE_FAST               1 (a)
             18 LOAD_CONST               0 (None)
             20 RETURN_VALUE

Python解释器是基于栈的虚拟机,LOAD_CONST和LOAD_FAST分别是把常量和变量入栈的操作,ROT_TWO是把栈顶两个元素翻转。赋值的时候虚拟机栈里面数据变化如下

# 第一步入栈
vm_stack = [..., 3, t+1] = [..., 3, 2]
# 第二步翻转
vm_stack = [..., 2, 3]
# 第三步赋值
t = vm_stack.pop() = 3
a = vm_stack.pop() = 2

简单来说,可以等价为先计算等式右边各项的值并且保存为一个元组。随后将这个中间变量–元组保存一下,再以从左到右的顺序一一对应赋值给左边变量

t = 1
t,a=3,t+1 
3 , t+1  ===> (3,2)
temp = (3,2)
t,a = temp

回看原来的代码:

在这里插入图片描述
在修改后的代码中,由于元组中的值从左到右依次赋给pre cur cur.next, 在将③赋值给cur后,cur指向了data为4的结点,因此cur.next代表的不再是data为3的结点的指针域,因此产生了错误。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值