为什么链式作业以这种方式工作?

pet*_*ang 12 python python-2.7 python-3.x

a = a[1:] = [2]在一篇文章中找到了作业.我在python3和python2中尝试过它; 这一切都有效,但我不明白它是如何工作的. =这里不像C; C =从右到左进行处理.python如何处理=运算符?

Sha*_*ger 15

根据任务的语言文档:

赋值语句计算表达式列表(请记住,这可以是单个表达式或以逗号分隔的列表,后者产生元组)并从左到右将单个结果对象分配给每个目标列表.

在这种情况下,a = a[1:] = [2]有一个表达式列表[2],以及两个"目标清单",a并且a[1:],在这里a是最左边的"目标清单".

您可以通过查看反汇编来了解其行为:

>>> import dis
>>> dis.dis('a = a[1:] = [2]')
  1           0 LOAD_CONST               0 (2)
              2 BUILD_LIST               1
              4 DUP_TOP
              6 STORE_NAME               0 (a)
              8 LOAD_NAME                0 (a)
             10 LOAD_CONST               1 (1)
             12 LOAD_CONST               2 (None)
             14 BUILD_SLICE              2
             16 STORE_SUBSCR
             18 LOAD_CONST               2 (None)
             20 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)

(可以忽略反汇编的最后两行,dis正在使函数包装器反汇编字符串)

需要注意的重要部分是,当你这样做时x = y = some_val,some_val被加载到堆栈上(在这种情况下是由LOAD_CONSTBUILD_LIST),然后堆栈条目被复制并从左到右分配给给定的目标.

所以当你这样做时:

a = a[1:] = [2]
Run Code Online (Sandbox Code Playgroud)

它对两个全新的list包含引用2,第一个动作是STORE这些引用中的一个a.接下来,它存储第二个引用a[1:],但由于切片赋值变异a,它必须a再次加载,这将获得list刚才存储的.幸运的是,它list可以抵御自我切片分配,或者我们有问题(它会永远读取它刚刚添加的值,直到我们用完内存并崩溃为止); 因此,它表现为[2]被指定为从索引1开始替换任何和所有元素的副本.

最终结果相当于如果你做了:

_ = [2]
a = _
a[1:] = _
Run Code Online (Sandbox Code Playgroud)

但它避免使用_名称.

要清楚,反汇编注释:

制作清单[2]:

  1           0 LOAD_CONST               0 (2)
              2 BUILD_LIST               1
Run Code Online (Sandbox Code Playgroud)

制作以下参考文献的副本[2]:

              4 DUP_TOP
Run Code Online (Sandbox Code Playgroud)

执行商店a:

              6 STORE_NAME               0 (a)
Run Code Online (Sandbox Code Playgroud)

执行商店a[1:]:

              8 LOAD_NAME                0 (a)
             10 LOAD_CONST               1 (1)
             12 LOAD_CONST               2 (None)
             14 BUILD_SLICE              2
             16 STORE_SUBSCR
Run Code Online (Sandbox Code Playgroud)


Pru*_*une 7

我理解这种作业的方式是,这相当于

temp = [2]
a = temp
a[1:] = temp
Run Code Online (Sandbox Code Playgroud)

得到的值[2, 2]与此解释一致.