Let's say I have a function getQ(x) which returns some number and it is pretty slow. Now, if I do this:

x = 10
x = getQ(x) if getQ(x) >= 0 else 0

does getQ get executed twice in such case?

Is this:

x = getQ(x)
x = x if x >= 0 else 0

quicker?

If so, is there a more elegant one-liner for such a situation?

有帮助吗?

解决方案

Yes, getQ would be called twice if the result is nonnegative, so the second would definitely be quicker in that case.

In this particular case, you could write x = max(getQ(x), 0). The "general" solution you're looking for is something like

x = (lambda x: x if x >= 0 else 0)(getQ(x))

I wouldn't recommend using this in real code, but it lets you bind a name while still keeping it one expression.

其他提示

You could use the dis module and clearly see that the function would be called twice in first case.

def fun1():
    ...:     x = sqrt(10) if sqrt(10)>=0 else 0
    ...:     

dis.dis(fun1)
  2           0 LOAD_GLOBAL              0 (sqrt) 
              3 LOAD_CONST               1 (10) 
              6 CALL_FUNCTION            1 (1 positional, 0 keyword pair)  // First Call
              9 LOAD_CONST               2 (0) 
             12 COMPARE_OP               5 (>=) 
             15 POP_JUMP_IF_FALSE       30 
             18 LOAD_GLOBAL              0 (sqrt) 
             21 LOAD_CONST               1 (10) 
             24 CALL_FUNCTION            1 (1 positional, 0 keyword pair) // Second Call
             27 JUMP_FORWARD             3 (to 33) 
        >>   30 LOAD_CONST               2 (0) 
        >>   33 STORE_FAST               0 (x) 
             36 LOAD_CONST               0 (None) 
             39 RETURN_VALUE         



def fun2():
    x = sqrt(10)
    x = x if x>=10 else 0



dis.dis(fun2)
  2           0 LOAD_GLOBAL              0 (sqrt) 
              3 LOAD_CONST               1 (10) 
              6 CALL_FUNCTION            1 (1 positional, 0 keyword pair) // Single call
              9 STORE_FAST               0 (x) 

  3          12 LOAD_FAST                0 (x) 
             15 LOAD_CONST               1 (10) 
             18 COMPARE_OP               5 (>=) 
             21 POP_JUMP_IF_FALSE       30 
             24 LOAD_FAST                0 (x) 
             27 JUMP_FORWARD             3 (to 33) 
        >>   30 LOAD_CONST               2 (0) 
        >>   33 STORE_FAST               0 (x) 
             36 LOAD_CONST               0 (None) 
             39 RETURN_VALUE         
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top