我在 python 中声明了四个变量 [a=1,b=2,c=3,d=0] 并使用“,”和“=”(简单赋值运算符)在一行代码中交换它们。
我有多个答案并感到困惑。请帮我...
案例 1:
a=1
b=2
c=3
d=0
a=a,b=b,c
print "a = " + str(a)
print "b = " + str(b)
print "c = " + str(c)
print "d = " + str(d)
案例 1 的输出:
a = 2
b = 3
c = 3
d = 0
案例 2:
a=1
b=2
c=3
d=0
b=a,b=b,c
print "a = " + str(a)
print "b = " + str(b)
print "c = " + str(c)
print "d = " + str(d)
案例 2 的输出:
a = 2
b = 3
c = 3
d = 0
案例 3:
a=1
b=2
c=3
d=0
c=a,b=b,c
print "a = " + str(a)
print "b = " + str(b)
print "c = " + str(c)
print "d = " + str(d)
案例 3 的输出:
a = 2
b = 3
c = (2,3)
d = 0
案例 4:
a=1
b=2
c=3
d=0
d=a,b=b,c
print "a = " + str(a)
print "b = " + str(b)
print "c = " + str(c)
print "d = " + str(d)
案例 4 的输出:
a = 2
b = 3
c = 3
d = (2,3)
混淆是:
在第 3 和第 4 种情况下,输出是正确的(如我所料)。但在 1 和 2 的情况下,a 的值为 2,b 的值为 3。我希望该值应该是 (2,3)。那么我的代码有什么问题?
[我的 Python 版本是 2.7]
最佳答案
tl; dr:多个赋值(一行上的多个 =
语句)从左到右计算,而不是从右到左(在计算右侧表达式之后)。
更复杂的是,您正在混合使用元组分配和“正常”分配。
元组赋值使用一个赋值运算符,因此要交换两个变量,请使用:
a, b = b, a
右侧必须评估为元素数量与左侧变量相同的元组。你这样做,那很好。现在,在您的示例中,您不仅要解包元组。当左侧只包含一个变量时,元组不会被解包,只是简单地赋值:
a, b = 1, 2
a = b, a
变成 (2, 1)
。当您在同一行上使用多个分配时,乐趣就开始了。这些是从左到右处理的。
所以,下面这个简单的例子:
a = b = c = 1
意味着 a
变成 1
,然后是 b
,然后是 c
。现在我们可以理解每种情况:
a=a,b=b,c
,其中 a = 1
、 b = 2
、 c = 3
。这变成:评估
b, c
-> (2, 3)
,然后将其分配给 a
-> a = (2, 3)
。然后将它分配给 a, b
,所以 a = 2
, b = 3
。结果: a = 2
、 b = 3
、 c = 3
。b=a,b=b,c
,其中 a = 1
、 b = 2
、 c = 3
。与之前的情况相同,但现在先设置
b = (2, 3)
,然后再次设置 b = 3
,结果与情况 1 相同。c=a,b=b,c
,其中 a = 1
、 b = 2
、 c = 3
。右侧的输入与案例 1. 和 2. 相同,但现在我们首先设置
c = (2, 3)
。最终结果如预期, a = 2
, b = 3
, c = (2, 3)
。d=a,b=b,c
,其中 a = 1
、 b = 2
、 c = 3
。与情况 3 相同。但现在我们改为设置
d
。没有惊喜。在这里让您感到困惑的是,在评估右侧之后,分配是从左到右处理的,而不是从右到左处理。
对于此类情况,实际上最简单的方法是运行您的代码(封装在函数中),通过
dis.dis()
function 来反汇编 Python 字节码:>>> import dis
>>> def f(): a=a,b=b,c
...
>>> dis.dis(f)
1 0 LOAD_FAST 0 (b)
3 LOAD_GLOBAL 0 (c)
6 BUILD_TUPLE 2
9 DUP_TOP
10 STORE_FAST 1 (a)
13 UNPACK_SEQUENCE 2
16 STORE_FAST 1 (a)
19 STORE_FAST 0 (b)
22 LOAD_CONST 0 (None)
25 RETURN_VALUE
这是第一种情况;注意在 BUILD_TUPLE
和 DUP_TOP
操作码(后者在堆栈上创建一个额外的副本以提供额外的赋值)之后,发生的第一件事是 STORE_FAST
上的 a
操作,然后是 UNPACK_SEQUENCE
(元组赋值操作码),以然后将结果存储到 a
和 b
中。关于python - 简单的赋值运算符在 Python 中变得复杂,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13657704/