【问题标题】:python parallel assignment of 3 variablespython并行赋值3个变量
【发布时间】:2021-03-13 01:55:45
【问题描述】:

我的问题来自一个流行的编码测试。

给定一个链defined as follows

class ListNode:
     def __init__(self, x):
         self.val = x
         self.next = None

如果我们要回链,例如:

输入:1->2->3->4->5->NULL

输出:5->4->3->2->1->NULL

可以像this这样解决:

class Solution:
    def reverseList(self, head: ListNode) -> ListNode:
        cur, pre = head, None
        while cur:
            tmp = cur.next 
            cur.next = pre 
            pre = cur      
            cur = tmp     
        return pre

但是有a more compact way,我真的无法理解:

class Solution:
    def reverseList(self, head: ListNode) -> ListNode:
        cur, pre = head, None
        while cur:
            cur.next, pre, cur = pre, cur, cur.next
        return pre

因为如果我将并行分配线更改为

            pre, cur, cur.next = cur, cur.next, pre

它不会再正常工作了。

我想知道python的并行赋值是如何工作的,尤其是在所有3个变量都是动态的情况下。

【问题讨论】:

  • 每件事都首先在右边进行评估,它本质上创建了一个长度为 3 的元组(尽管作为 CPython 实现细节/微优化,编译器实际上避免在 2 和可能 3 的情况下生成元组)。然后那个元组'项目从左到右分配到左侧的目标列表

标签: python python-3.x variable-assignment


【解决方案1】:

当你写一个并行作业时

x, y, z = a, b, c

相当于

temp = (a, b, c)
x = temp[0]
y = temp[1]
z = temp[2]

所以在失败的版本中,它相当于

temp = (cur, cur.next, pre)
pre = temp[0]
cur = temp[1]
cur.next = temp[2]

将此与工作版本进行比较:

cur.next = temp[0]
pre = temp[1]
cur = temp[2]

不同之处在于,在您的版本中,您分配给cur.next 您将cur 步进到cur.next,因此您实际上分配给原始cur.next.next

【讨论】:

  • 我不明白解释器实际上在做什么。它是否遍历左侧赋值?像 a , _ , c , d[a] , a.next = tuple 这样更复杂的解包会是什么样子?
  • 是的,这就是它所做的一切。这几乎与我在回答中显示的完全一样。
  • a = tuple[0]; _ = tuple[1]; c = tuple[2]; d[a] = tuple[3]; a.next = tuple[4]
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-21
  • 2011-09-23
  • 2013-09-13
  • 2016-01-24
  • 2015-01-26
相关资源
最近更新 更多