我在 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
案例三:
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
操作码(后者在堆栈上创建一个额外的副本以服务于额外的分配)之后,发生的第一件事是
操作,后跟 a
上的 STORE_FASTUNPACK_SEQUENCE
(元组分配操作码),然后将结果存储到 a
和 b
。
关于python - 简单的赋值运算符在 Python 中变得复杂,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13657704/