Python 拆包:[x,y],(x,y),x,y-有什么区别?
在Python中,用Python 拆包:[x,y],(x,y),x,y-有什么区别?,python,iterable-unpacking,Python,Iterable Unpacking,在Python中,用[]解压函数调用、用()解压函数调用或不解压函数调用之间有什么区别 def(): 返回0,1 a、 b=f()#1 [a,b]=f()#2 (a,b)=f()#3 没有区别。无论使用哪种语法序列,都会生成相同的字节码 >>> def f(): ... return 0, 1 ... >>> import dis >>> dis.dis('[a,b] = f()') 1 0 LOAD_NAME
[]
解压函数调用、用()
解压函数调用或不解压函数调用之间有什么区别
def():
返回0,1
a、 b=f()#1
[a,b]=f()#2
(a,b)=f()#3
没有区别。无论使用哪种语法序列,都会生成相同的字节码
>>> def f():
... return 0, 1
...
>>> import dis
>>> dis.dis('[a,b] = f()')
1 0 LOAD_NAME 0 (f)
2 CALL_FUNCTION 0
4 UNPACK_SEQUENCE 2
6 STORE_NAME 1 (a)
8 STORE_NAME 2 (b)
10 LOAD_CONST 0 (None)
12 RETURN_VALUE
>>> dis.dis('(a,b) = f()')
1 0 LOAD_NAME 0 (f)
2 CALL_FUNCTION 0
4 UNPACK_SEQUENCE 2
6 STORE_NAME 1 (a)
8 STORE_NAME 2 (b)
10 LOAD_CONST 0 (None)
12 RETURN_VALUE
>>> dis.dis('a, b = f()')
1 0 LOAD_NAME 0 (f)
2 CALL_FUNCTION 0
4 UNPACK_SEQUENCE 2
6 STORE_NAME 1 (a)
8 STORE_NAME 2 (b)
10 LOAD_CONST 0 (None)
12 RETURN_VALUE
在每种情况下,只需调用f
,然后使用UNPACK\u SEQUENCE
生成要分配给a
和b
的值
即使你想说字节码是CPython的一个实现细节,链式赋值的定义也不是。给定 意思与
tmp = f()
x = tmp
[a, b] = tmp
x
分配的是f()
(一个元组)的结果,而不是“列表”[a,b]
最后,这里是赋值语句的语法:
assignment_stmt ::= (target_list "=")+ (starred_expression | yield_expression)
target_list ::= target ("," target)* [","]
target ::= identifier
| "(" [target_list] ")"
| "[" [target_list] "]"
| attributeref
| subscription
| slicing
| "*" target
可以说,
“[”[target_list]“]”
可以而且应该在Python3中删除。现在很难实现这样一个突破性的更改,因为声明倾向于避免将来对Python进行任何2到3转换的更改。正如另一个答案所解释的,没有语义上的差异。喜欢一种形式胜过另一种形式的唯一原因是视觉清晰度x,y=f()
通常比较整洁,但有时可能会编写类似于[(id,)]=do\u sql\u query()
的内容,以指示结果应该是一个包含元组的列表。赋值目标[(id,)]
在语义上等同于(id,),
,但它向人类读者传达了更多信息。没有任何区别。如果您需要更具说服力的话,可以使用dis
模块来分解包含每个版本的函数,并观察它们的字节码是否相同。您唯一能找到的参考是您是否调用了type(thing)。\uuu name\uu不确定它是否是重复的,肯定相关:@reece没有任何东西可以调用type
;这里的括号纯粹是语法上的[a,b]=f()
不会在此处创建任何类型的列表。在这种情况下,所有列表都是冗余的。但是括号对于解包嵌套的东西是有用的:a,(b,c)=[0,1],[2,3]
导致a=[0,1]
,b=2
,c=3
。另外,我相信赋值操作符的定义:=/code>排除了任何类似(x:=[a,b])=f()的技巧。(这至少是一个语法错误。)
assignment_stmt ::= (target_list "=")+ (starred_expression | yield_expression)
target_list ::= target ("," target)* [","]
target ::= identifier
| "(" [target_list] ")"
| "[" [target_list] "]"
| attributeref
| subscription
| slicing
| "*" target