Python 3 中使用链表进行三个(或更多)不同变量赋值的操作顺序

问题描述 投票:0回答:1

我正在编写简单的代码来反转链表,并意识到可以在一行上完成分配,我发现这很酷:

    def Reverse(head):
      prev_node = None
      curr_node = head

      while curr_node:
        prev_node, curr_node.next, curr_node = curr_node, prev_node, curr_node.next

      return prev_node

但我注意到,如果我反转左侧的 curr_node.next (与右侧的 prev_node 相对应)和左侧的 curr_node (右侧的 curr_node.next)之间的分配顺序,代码就会失败

    def Reverse(head):
      prev_node = None
      curr_node = head
      print(curr_node.data)
      print(curr_node.next.data)
      print(prev_node)

      while curr_node:
        prev_node, curr_node, curr_node.next = curr_node, curr_node.next, prev_node

      return prev_node

输入的是

1 2 3 4

输出为

1
2
None

但是 while 循环会产生以下错误(仅在第二个代码块上;第一个代码块运行良好)

      prev_node, curr_node, curr_node.next = curr_node, curr_node.next, prev_node
    AttributeError: 'NoneType' object has no attribute 'next'

我能找到的关于该主题的最接近的讨论是这里。这表示首先从左到右评估 RHS。我认为这意味着先存储 curr_node,然后存储 prev_node,然后存储 curr_node.next。然后它们分别被分配给prev_node、curr_node.next和curr_node。我看不出第一个例子和第二个例子有什么区别。我错过了一些简单的事情吗?

有谁知道为什么第一个示例运行而第二个示例产生错误?

python python-3.x linked-list variable-assignment iterable-unpacking
1个回答
4
投票

是的,元组赋值首先评估右侧(从左到右),然后执行赋值,从左到右。

来自赋值语句文档

赋值语句计算表达式列表(请记住,这可以是单个表达式或逗号分隔的列表,后者生成一个元组),并将单个结果对象从左到右分配给每个目标列表。

在第二种情况下,您将

None
分配给
curr_node
,因此下一次对
curr_node.next
的分配失败。

换句话说,这是有效的:

prev_node, curr_node.next, curr_node = curr_node, None, None

(执行

curr_node
时,假设
next
仍然是具有
curr_node.next = None
属性的 Node 实例),但如果交换参数:

prev_node, curr_node, curr_node.next = curr_node, None, None

现在

curr_node = None
curr_node.next = prev_node
之前执行。

这是一个简化的演示,向您展示作业顺序的重要性:

>>> class Node:
...     next = None
...
>>> curr_node = Node()
>>> curr_node.next, curr_node = None, None  # first attribute, then name
>>> curr_node = Node()
>>> curr_node, curr_node.next = None, None  # first the name, no attribute anymore
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'next'
© www.soinside.com 2019 - 2024. All rights reserved.