5

Which is better?

if not var:
    var = get_var()
(or)

var = var or get_var()

Also, How do I know the better of the two?
edit:
One more option from steve,

var = var if var else get_var()
5
  • 3
    Also consider : var = var if var else getvar () - not necessarily a recommendation in this case, just another option. Commented Mar 11, 2010 at 6:12
  • What if get_var() returns 0? You will keep calling it, even though you already know the value. Commented Mar 11, 2010 at 6:33
  • that should have been get_new_var().. Commented Mar 11, 2010 at 7:13
  • This doesn't "Avoid" an if-condition at all. What are you asking? Commented Mar 11, 2010 at 11:07
  • If you want a new var every time, why don't you just code var = get_new_var()? Commented Mar 12, 2010 at 15:37

9 Answers 9

7

The better is the one you like better. I would use first version with if but this is very personal.

Sign up to request clarification or add additional context in comments.

Comments

7

When two style variations are so close stylistically, I use timeit as the tie-breaker: faster must mean closer to Python's mainstream, i.e., better. Hey, it's better than endless debate, y?-) So:

$ python -mtimeit -s'var=0; getvar=lambda:0' 'var = var or getvar()'
1000000 loops, best of 3: 0.359 usec per loop
$ python -mtimeit -s'var=0; getvar=lambda:0' 'if not var: var = getvar()'
1000000 loops, best of 3: 0.361 usec per loop
$ python -mtimeit -s'var=1; getvar=lambda:1' 'var = var or getvar()'
10000000 loops, best of 3: 0.123 usec per loop
$ python -mtimeit -s'var=1; getvar=lambda:1' 'if not var: var = getvar()'
10000000 loops, best of 3: 0.0899 usec per loop

the if has it -- equivalent when var is false, faster when it's true.

6 Comments

When nothing else matters, micro-optimize!
@Chris, I see it more as "find out what the Python mainstream is" -- Python core developers (me included) end up spending lots more time optimizing usage that's frequent and appreciated, rather than marginal and sneered at, so timeit is a way to capture the overall sum of their (our) efforts for an otherwise-moot decision.
seems a little contradictionary to me, how else did they implement short cicuiting then?
@Alex - My comment was meant to be more tongue-in-cheek than it reads. Forgive my amateur internet-sarcasm skills.
@Chris, sure, just wanted to clarify my reasoning. @Johannes, x=x doesn't get optimized away by the Python compiler, which is really a super-simple compiler, so the fact that the short-circuiting results in the equivalent of var=var does not make the latter "free"!-)
|
4

Actually, if you are trying to determine if var has been previously set using a call to get_var, then I would contend that both forms are wrong. Python treats a number of perfectly ordinary values as evaluating to a boolean 'false': 0, None, [], (,), set(), and {}. So let's say var is going to be an integer, and get_var() happens to return 0. Now, regardless of which form you use, get_var() will get called again and again, even though we already know that var is 0!

There are several methods for detecting whether a variable has been defined or not:

  • look in the dict returned by globals() or locals()

  • wrap the statement var = var in a try/except block, trapping on NameError

  • use a sentinel value like None, and initialize var to this value; then you can test for if var is None: var = get_var() (using 'is', not '=='). If you are unlucky, and None is a potential value to be returned from get_var(), then you'll need to define your own special not-yet-defined value, using something like NOT_DEFINED = object(), initialize var with it, and then you can test for if var is NOT_DEFINED.

Comments

3

To me, the first idiom, the one using the explicit if, is preferable because more explicit.

However I've seen the or construct being referenced as the preferred / more pythonic one.

So, on the one hand, Explicit is better than implicit (Zen citation), on the other hand, the short expression can be viewed as pythonic (although shorter isn't equivalent to pythonic in all cases!)

A closely related SO question is most idiomatic way to convert None to empty string, and both the if and the or idioms were listed there.

Comments

2

the first version is more intuitive to me. But then again, its all about your own taste.

Comments

1

Second one is more pythonic, and I normally use that.

2 Comments

does that mean that the if construct is not Pythonic? what constitutes "Pythonic" ?
IMO it's more Pythonic if var happens to be boolean. Otherwise, probably not, though the context may change my mind.
1

Neither is wrong.

The former is clearer to understand for someone reading the code.

Ask yourself if, when you are thinking about the problem you are trying to solve, the concepts that come to mind are closer to "if this, then that" or "a logical OR of two almost, but not quite, Boolean variables."

Comments

1

Both will eventually compile to the same code, given that or is a short-circuit operator (it doesn't evaluate the right hand argument if left hand is true).

I'd prefer the first one as it expresses your intent more clearly. The second one is probably more compact.

Comments

1

The interpreter will likely execute them both the way. There are tradeoffs regarding code readability. Which statement is easier to recognize what it does? Certainly, the first is much clearer. For me, reading this post, I had to think more about the second one. I would use the first due to increased readability, even if the second statement is slightly 'sexier'.

Hope this helps.
-tjw

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.