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_CONST和BUILD_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)
我理解这种作业的方式是,这相当于
temp = [2]
a = temp
a[1:] = temp
Run Code Online (Sandbox Code Playgroud)
得到的值[2, 2]与此解释一致.
| 归档时间: |
|
| 查看次数: |
774 次 |
| 最近记录: |