加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

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

发布时间:2020-12-20 12:29:23 所属栏目:Python 来源:网络整理
导读:我在 python中声明了四个变量[a = 1,b = 2,c = 3,d = 0],并使用’,’和’='(简单赋值运算符)将它们换成一行代码. 我有多个答案,并感到困惑.请帮我… 情况1: a=1b=2c=3d=0a=a,b=b,cprint "a = " + str(a)print "b = " + str(b)print "c = " + str(c)print "d
我在 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,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,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,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,c,其中a = 1,c = 3.

这变成:评估b,c – > (2,3),然后将其分配给 – > a =(2,3).然后将其分配给a,b,所以a = 2,b = 3.结果:a = 2,b = 3,c = 3.
> b = a,c = 3.

与之前的情况相同,但现在首先设置b =(2,然后再次设置b = 3,结果与情况1相同.
> c = a,c = 3.

右侧输入与情况1和2相同,但现在我们首先设置c =(2,3).最终结果如预期,a = 2,c =(2,3).
> d = a,c = 3.

与案例3相同,但现在我们设置了d.没有惊喜.

让你感到困惑的是,在评估右侧之后,分配从左到右处理,而不是从右到左处理.

对于像这样的情况,它实际上最容易运行你的代码(包含在一个函数中),通过dis.dis() function来反汇编python字节码:

>>> import dis
>>> def f(): a=a,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_FAST操作,后跟UNPACK_SEQUENCE(元组赋值操作码),然后将结果存储到a和b中.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读