문제

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