Python: avoiding if condition?
Which is be开发者_Python百科tter?
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()
The better is the one you like better. I would use first version with if
but this is very personal.
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
.
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 NameErroruse 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 likeNOT_DEFINED = object()
, initialize var with it, and then you can test forif var is NOT_DEFINED
.
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.
the first version is more intuitive to me. But then again, its all about your own taste.
Second one is more pythonic, and I normally use that.
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."
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.
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
精彩评论