简单赋值运算符在Python中变得复杂

简单赋值运算符在Python中变得复杂,python,operators,variable-assignment,Python,Operators,Variable Assignment,我在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) a = 2 b = 3 c = 3 d = 0 a=1 b=2 c=3 d=0 b=a,

我在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)
a = 2
b = 3
c = 3
d = 0
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)
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)
a = 2
b = 3
c = (2,3)
d = 0
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)
a = 2
b = 3
c = 3
d = (2,3)
案例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)
a = 2
b = 3
c = 3
d = 0
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)
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)
a = 2
b = 3
c = (2,3)
d = 0
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)
a = 2
b = 3
c = 3
d = (2,3)

案例2:

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)
a = 2
b = 3
c = 3
d = 0
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)
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)
a = 2
b = 3
c = (2,3)
d = 0
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)
a = 2
b = 3
c = 3
d = (2,3)
案例2的输出:

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)
a = 2
b = 3
c = 3
d = 0
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)
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)
a = 2
b = 3
c = (2,3)
d = 0
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)
a = 2
b = 3
c = 3
d = (2,3)

案例3:

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)
a = 2
b = 3
c = 3
d = 0
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)
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)
a = 2
b = 3
c = (2,3)
d = 0
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)
a = 2
b = 3
c = 3
d = (2,3)
案例3的输出:

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)
a = 2
b = 3
c = 3
d = 0
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)
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)
a = 2
b = 3
c = (2,3)
d = 0
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)
a = 2
b = 3
c = 3
d = (2,3)

案例4:

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)
a = 2
b = 3
c = 3
d = 0
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)
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)
a = 2
b = 3
c = (2,3)
d = 0
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)
a = 2
b = 3
c = 3
d = (2,3)
案例4的输出:

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)
a = 2
b = 3
c = 3
d = 0
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)
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)
a = 2
b = 3
c = (2,3)
d = 0
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)
a = 2
b = 3
c = 3
d = (2,3)
困惑是:

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)
a = 2
b = 3
c = 3
d = 0
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)
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)
a = 2
b = 3
c = (2,3)
d = 0
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)
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相同。现在我们首先设置
    c=(2,3)
    。预期的最终结果,
    a=2
    b=3
    c=(2,3)

  • d=a,b=b,c
    ,其中
    a=1
    b=2
    c=3

    与案例3相同。但是现在我们改为设置
    d
    。没有意外

  • 让您感到困惑的是,在计算了右侧之后,作业是从左到右处理的,而不是从右到左处理的

    对于这样的情况,实际上运行代码(包装在函数中)最简单的方法是通过以下步骤来分解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        
    
    这是第一例,;请注意,在
    构建元组
    DUP\u TOP
    操作码(后者在堆栈上创建一个额外的副本以提供额外的分配)之后,首先发生的是
    a
    上执行的
    存储快速
    操作,然后是
    解包序列
    (元组分配操作码),然后将结果存储到
    a
    b