python使用逗号交换值导致混乱

时间:2019-04-25 13:23:36

标签: python python-3.x swap

这涉及到我在尝试解决链表反向问题时遇到的问题。

首先让我输入一些初步的代码来定义链表和快速方法以生成链表:

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

    def __repr__(self):
        if self.next:
            return "{}->{}".format(self.val, repr(self.next))
        else:
            return "{}".format(self.val)

def genNode(*nodes, end=None):
    if len(nodes) == 1 and type(nodes[0]) == list:
        nodes = nodes[0]
    for i in nodes[::-1]:
        n = ListNode(i)
        n.next, end = end, n
    return n if nodes else None

我遇到的问题是我发现交换机制仍然取决于我编写的变量的顺序。

最初,当我们谈论在python中交换值时,我们可以做到:

a, b = b, a

如果有的话,它应该以相同的方式工作

b, a = a, b

我要编写的这种反向链表方法有3个变量交换,其思想很简单,即创建一个虚拟头,并在dummy和dummy.next之间不断添加节点,以便可以将其反转。

def rev(head):
    dummy = ListNode('X')
    while head:
        dummy.next, head.next, head = head, dummy.next, head.next
    return dummy.next

a = genNode(1,2,3,4)
print(rev(a)) # >>> 4->3->2->1

但是,如果我稍微切换3个变量的顺序,则:

def rev2(head):
    dummy = ListNode('X')
    while head:
        dummy.next, head, head.next, = head, head.next, dummy.next,
    return dummy.next

a = genNode(1,2,3,4)
print(rev2(a))  # >>> AttributeError: 'NoneType' object has no attribute 'next'

所以似乎序列在这里很重要,如果有两个以上的变量,谁能让我知道python如何评估交换值。

谢谢!

3 个答案:

答案 0 :(得分:4)

从左到右

https://docs.python.org/3/reference/simple_stmts.html#assignment-statements

CPython实现的详细信息:在当前的实现中,目标的语法与表达式的语法相同,并且无效的语法在代码生成阶段被拒绝,从而导致不太详细的错误消息。

尽管赋值的定义意味着左侧和右侧之间的重叠是“同时”的(例如,a,b = b,一个交换两个变量),在Assigned-to的集合内重叠变量从左到右发生,有时会导致混乱。例如,以下程序打印[0,2]:

x = [0, 1]
i = 0
i, x[i] = 1, 2         # i is updated, then x[i] is updated
print(x)

答案 1 :(得分:1)

下面的一个简单示例应向您展示对诸如ListNode之类的类使用交换的注意事项

让我们定义一个3元素链接列表。

a = ListNode(1)
b = ListNode(2)
c = ListNode(3)
a.next = b
b.next = c
print(a)
#1->2->3

现在,如果我们将b和c交换,它将没有任何作用

b,c = c,b
print(a)
#1->2->3

如果我们交换a和b,则链表会更改。

a,b=b,a
print(a)
#2->3

类似地进行a和c交换。

a,c=c,a
print(a)
#3

因此您可以看到,使用简单的交换逻辑在将其应用于ListNode时是不一致的,因此应避免使用。

答案 2 :(得分:-1)

如果有两个以上的变量,则其作用与两个相同。您将它们按所需的最终顺序放置:

>>> a = 1
>>> b = 2
>>> c = 3
>>> c,b,a = a,b,c
>>> a,b,c
(3, 2, 1)