关于python:从函数调用中分配多个返回值的性能

Performance of assigning multiple return values from function call

本问题已经有最佳答案,请猛点这里访问。

我想知道是否有一种方法可以将函数的输出分配给变量,而只需要运行一次函数。例如,假设我有这样的函数:

1
2
def my_func(x):
    return x+1, x**2, x**3

然后我想将每个输出存储为一个变量,所以通常我会在后面对此进行编码:

1
2
3
var1 = my_func(2)[0]
var2 = my_func(2)[1]
var3 = my_func(2)[2]

但是根据我的理解,上面的每一行都需要函数再次运行。如果我有一个较长的函数,那么在同一时间将它们全部分配会更方便,只运行一次函数。有办法吗?


两种可能性:

将函数的返回值(即tuple)赋给变量,并访问其元素:

1
2
3
4
var = my_func(2)
var1 = var[0]
var2 = var[1]
var3 = var[2]

或者使用解包:

1
var1, var2, var3 = my_func(2)

回复:在大多数情况下,哪种方法运行得更快?

让我们比较一下拆卸(与>的区别):

dis.dis('t=my_func(2);d=t[0]+t[1]+t[2]')

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  1           0 LOAD_NAME                0 (my_func)
              2 LOAD_CONST               0 (2)
              4 CALL_FUNCTION            1
           >  6 STORE_NAME               1 (t)
              8 LOAD_NAME                1 (t)
           > 10 LOAD_CONST               1 (0)
           > 12 BINARY_SUBSCR
             14 LOAD_NAME                1 (t)
           > 16 LOAD_CONST               2 (1)
           > 18 BINARY_SUBSCR
             20 BINARY_ADD
             22 LOAD_NAME                1 (t)
           > 24 LOAD_CONST               0 (2)
           > 26 BINARY_SUBSCR
             28 BINARY_ADD
             30 STORE_NAME               2 (d)
             32 LOAD_CONST               3 (None)
             34 RETURN_VALUE

dis.dis('a,b,c=my_func(2);d=a+b+c')

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  1           0 LOAD_NAME                0 (my_func)
              2 LOAD_CONST               0 (2)
              4 CALL_FUNCTION            1
          >   6 UNPACK_SEQUENCE          3
          >   8 STORE_NAME               1 (a)
          >  10 STORE_NAME               2 (b)
          >  12 STORE_NAME               3 (c)
             14 LOAD_NAME                1 (a)
             16 LOAD_NAME                2 (b)
             18 BINARY_ADD
             20 LOAD_NAME                3 (c)
             22 BINARY_ADD
             24 STORE_NAME               4 (d)
             26 LOAD_CONST               1 (None)
             28 RETURN_VALUE

因此,第一种方法在每次使用变量时都会多接受两条指令(load_const,binary_subscr),而第二种方法在创建变量时会多接受一条指令。

这种差别实际上毫无意义。


是的,您可以通过序列解包来完成此操作:

1
2
3
4
def my_func(x):
    return x+1, x**2, x**3

var1, var2, var3 = my_func(2)

这个特性在docs:tuples和sequences中描述。