用 [ ] 解压 python 元组
Unpack python tuple with [ ]'s
我知道解压元组的规范方法是这样的
a, b, c = (1, 2, 3)
# or
(a,b,c) = (1, 2, 3)
但注意到您可以像这样解压元组
[a, b, c] = (1, 2, 3)
第二种方法是否会因某种强制转换或列表构造而产生任何额外成本?有没有一种方法可以检查 python 解释器如何处理这个类似于从编译器查看程序集?
使用godbolt,语言选择Python
,然后输入三行代码,可以看到它们的字节码都是一样的:
1 0 LOAD_CONST 5 ((1, 2, 3))
2 UNPACK_SEQUENCE 3
4 STORE_NAME 0 (a)
6 STORE_NAME 1 (b)
8 STORE_NAME 2 (c)
2 10 LOAD_CONST 6 ((1, 2, 3))
12 UNPACK_SEQUENCE 3
14 STORE_NAME 0 (a)
16 STORE_NAME 1 (b)
18 STORE_NAME 2 (c)
3 20 LOAD_CONST 7 ((1, 2, 3))
22 UNPACK_SEQUENCE 3
24 STORE_NAME 0 (a)
26 STORE_NAME 1 (b)
28 STORE_NAME 2 (c)
所以,它们是相同的,只是语法不同。
不,这些都是完全等价的。从经验上看这个问题的一种方法是使用 dis
分解器:
>>> import dis
>>> dis.dis("a, b, c = (1, 2, 3)")
1 0 LOAD_CONST 0 ((1, 2, 3))
2 UNPACK_SEQUENCE 3
4 STORE_NAME 0 (a)
6 STORE_NAME 1 (b)
8 STORE_NAME 2 (c)
10 LOAD_CONST 1 (None)
12 RETURN_VALUE
>>> dis.dis("(a, b, c) = (1, 2, 3)")
1 0 LOAD_CONST 0 ((1, 2, 3))
2 UNPACK_SEQUENCE 3
4 STORE_NAME 0 (a)
6 STORE_NAME 1 (b)
8 STORE_NAME 2 (c)
10 LOAD_CONST 1 (None)
12 RETURN_VALUE
>>> dis.dis("[a, b, c] = (1, 2, 3)")
1 0 LOAD_CONST 0 ((1, 2, 3))
2 UNPACK_SEQUENCE 3
4 STORE_NAME 0 (a)
6 STORE_NAME 1 (b)
8 STORE_NAME 2 (c)
10 LOAD_CONST 1 (None)
12 RETURN_VALUE
>>>
从形式语言规范来看,这是detailed here。这是“目标列表”的一部分,相关引用:
Assignment of an object to a target list, optionally enclosed in
parentheses or square brackets, is recursively defined as
follows....
我已经使用 Linux perf 工具检查了执行时间和循环次数。所有 3 个程序都显示相同的执行时间,所以我认为没有任何额外费用。
我知道解压元组的规范方法是这样的
a, b, c = (1, 2, 3)
# or
(a,b,c) = (1, 2, 3)
但注意到您可以像这样解压元组
[a, b, c] = (1, 2, 3)
第二种方法是否会因某种强制转换或列表构造而产生任何额外成本?有没有一种方法可以检查 python 解释器如何处理这个类似于从编译器查看程序集?
使用godbolt,语言选择Python
,然后输入三行代码,可以看到它们的字节码都是一样的:
1 0 LOAD_CONST 5 ((1, 2, 3))
2 UNPACK_SEQUENCE 3
4 STORE_NAME 0 (a)
6 STORE_NAME 1 (b)
8 STORE_NAME 2 (c)
2 10 LOAD_CONST 6 ((1, 2, 3))
12 UNPACK_SEQUENCE 3
14 STORE_NAME 0 (a)
16 STORE_NAME 1 (b)
18 STORE_NAME 2 (c)
3 20 LOAD_CONST 7 ((1, 2, 3))
22 UNPACK_SEQUENCE 3
24 STORE_NAME 0 (a)
26 STORE_NAME 1 (b)
28 STORE_NAME 2 (c)
所以,它们是相同的,只是语法不同。
不,这些都是完全等价的。从经验上看这个问题的一种方法是使用 dis
分解器:
>>> import dis
>>> dis.dis("a, b, c = (1, 2, 3)")
1 0 LOAD_CONST 0 ((1, 2, 3))
2 UNPACK_SEQUENCE 3
4 STORE_NAME 0 (a)
6 STORE_NAME 1 (b)
8 STORE_NAME 2 (c)
10 LOAD_CONST 1 (None)
12 RETURN_VALUE
>>> dis.dis("(a, b, c) = (1, 2, 3)")
1 0 LOAD_CONST 0 ((1, 2, 3))
2 UNPACK_SEQUENCE 3
4 STORE_NAME 0 (a)
6 STORE_NAME 1 (b)
8 STORE_NAME 2 (c)
10 LOAD_CONST 1 (None)
12 RETURN_VALUE
>>> dis.dis("[a, b, c] = (1, 2, 3)")
1 0 LOAD_CONST 0 ((1, 2, 3))
2 UNPACK_SEQUENCE 3
4 STORE_NAME 0 (a)
6 STORE_NAME 1 (b)
8 STORE_NAME 2 (c)
10 LOAD_CONST 1 (None)
12 RETURN_VALUE
>>>
从形式语言规范来看,这是detailed here。这是“目标列表”的一部分,相关引用:
Assignment of an object to a target list, optionally enclosed in parentheses or square brackets, is recursively defined as follows....
我已经使用 Linux perf 工具检查了执行时间和循环次数。所有 3 个程序都显示相同的执行时间,所以我认为没有任何额外费用。