Domanda

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?

È stato utile?

Soluzione

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.

Altri suggerimenti

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         
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top