python 使用逗号交换值会造成混淆
python swaping values using comma is causing confusions
这涉及到我在尝试解决链表反向问题时遇到的问题。
先放一些初步的链表定义代码和快速生成链表的方法:
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 head,并在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'
所以看起来序列在这里很重要,谁能告诉我如果变量超过 2 个,python 如何评估交换值。
谢谢!
如果有两个以上的变量,它的工作原理与两个相同。您将它们按所需的最终顺序排列:
>>> a = 1
>>> b = 2
>>> c = 3
>>> c,b,a = a,b,c
>>> a,b,c
(3, 2, 1)
从左到右
看看https://docs.python.org/3/reference/simple_stmts.html#assignment-statements
CPython 实现细节:在当前实现中,目标的语法与表达式的语法相同,在代码生成阶段拒绝无效语法,导致错误消息不那么详细。
虽然赋值的定义暗示左侧和右侧之间的重叠是“同时”的(例如a,b = b,a交换两个变量),但在分配的集合中重叠-to 变量从左到右出现,有时会导致混淆。例如,以下程序打印 [0, 2]:
x = [0, 1]
i = 0
i, x[i] = 1, 2 # i is updated, then x[i] is updated
print(x)
下面的一个简单示例应该向您展示使用交换 class 的注意事项,例如 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
时是不一致的,因此应该避免。
这涉及到我在尝试解决链表反向问题时遇到的问题。
先放一些初步的链表定义代码和快速生成链表的方法:
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 head,并在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'
所以看起来序列在这里很重要,谁能告诉我如果变量超过 2 个,python 如何评估交换值。
谢谢!
如果有两个以上的变量,它的工作原理与两个相同。您将它们按所需的最终顺序排列:
>>> a = 1
>>> b = 2
>>> c = 3
>>> c,b,a = a,b,c
>>> a,b,c
(3, 2, 1)
从左到右
看看https://docs.python.org/3/reference/simple_stmts.html#assignment-statements
CPython 实现细节:在当前实现中,目标的语法与表达式的语法相同,在代码生成阶段拒绝无效语法,导致错误消息不那么详细。
虽然赋值的定义暗示左侧和右侧之间的重叠是“同时”的(例如a,b = b,a交换两个变量),但在分配的集合中重叠-to 变量从左到右出现,有时会导致混淆。例如,以下程序打印 [0, 2]:
x = [0, 1]
i = 0
i, x[i] = 1, 2 # i is updated, then x[i] is updated
print(x)
下面的一个简单示例应该向您展示使用交换 class 的注意事项,例如 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
时是不一致的,因此应该避免。