views:

203

answers:

7

Assuming that x is an integer, the construct if x: is functionally the same as if x != 0: in Python. Some languages' style guides explicitly forbid against the former -- for example, ActionScript/Flex's style guide states that you should never implicitly cast an int to bool for this sort of thing.

Does Python have a preference? A link to a PEP or other authoritative source would be best.

+1  A: 

Typically, I read:

if(x) to be a question about existence.

if( x != 0) to be a question about a number.

Paul Nathan
Not totally true. PEP 8 (Python style guide) specifically says "beware of writing `if x` when you really mean `if x is not None`"
Yuval A
@Yuval: I'm offering my perspective on how I interpret the meaning of the two forms of if.
Paul Nathan
Fair enough, just a friendly warning to future Python users :)
Yuval A
Existence? Do you mean "emptiness of a container"? In any case, code that has redundant parentheses in `if` statements and doesn't adhere to PEP 8 spacing can only be read as a portent of doom :-)
John Machin
@Paul - consider this test case, when referring to "existence": suppose `a = ()`. `a` *exists*, and in that sense it is `True`, but it is also an empty sequence, rendering it `False` in the boolean sense. `a` will not pass an `if a:` clause.
Yuval A
@Yuval: whether `a` *exists* or not means different things to different people. I would expect `if a:` to raise `NameError` if `a` didn't exist! :-).
Alok
@Yuval: Sure - I'm specifying interpretative opionion
Paul Nathan
+7  A: 

The construct: if x: is generally used to check against boolean values.

For ints the use of the explicit x != 0 is preferred - along the lines of explicit is better than implicit (PEP 20 - Zen of Python).

Yuval A
I prefer `if x:` rather than `if x != 0:` because it's simpler. "Explicit is better than implicit" can be used to justify `if x is True:` or even `if x == True:` too. :-)
Alok
@Alok - that is your personal preference, and that is fine. But `if x:` is the Pythonic idiom for testing boolean values, not integers.
Yuval A
@Yuval A: Are you saying `if x:` should be only used where `x` evaluates to type bool? `if x:` is "generally" also used where `x` refers to a container -- do you prefer the more explicit `if len(x) != 0:` ??
John Machin
@John - depending on the context, yes.
Yuval A
@Yuval: I asked TWO questions; to which question(s) does your answer relate?
John Machin
@Yuval: many of the types in Python have sensible values in boolean contexts precisely because you *can* (and should) use them as such. Otherwise, an instance of the `list` type should raise `TypeError` or some other exception if you tried doing `if x:` when x is of `list` type.For the same reason, I prefer `if (p)` to `if (p != NULL)` in C for pointer types. If one were to take "explicit is better..." to its logical end, one should write `if ((x == True) == True):`, or better, `if (((x == True) == True) == True):`, or even better... (you get the idea :-) ).
Alok
@John Generally, no. Containers are also done using "if container" (or "while container". For example, see the Python example implementation of itertools.cycle: http://docs.python.org/library/itertools.html#itertools.cycle
Devin Jeanpierre
@Alok : Don't be silly. This is simply an application of common sense. "if x != 0" states clearly that it's a number, in context, and thus aids readability. This was mentioned in Code Complete somewhere or something, so listen to that guy if you don't believe me.
Devin Jeanpierre
@Devin: I am not saying that `if x == 0:` should never be written. I am saying that I prefer `if x:` in general. I am also making a (separate) point that there is a limit to how much better "explicit" is to "implicit" - surely there is a limit, as my obviously absurd example showed.
Alok
It's okay to write `if x:` if `x` is _semantically_ boolean, regardless of what its actual type is. If, however, it is otherwise treated as something else (e.g. a number), and the check is for a _number_ (e.g. you are checking for 0 to avoid a divide by zero), then shortening it is misleading.
Pavel Minaev
A: 

Wouldn't if x is not 0: be the preferred method in Python, compared to if x != 0:?

Yes, the former is a bit longer to write, but I was under the impression that is and is not are preferred over == and !=. This makes Python easier to read as a natural language than as a programming language.

Brian S
Wrong. It's an implementation detail of CPython that small integers (including 0) are interned. So using "is" works with 0 but not 666. `0 is 3 + (-3)` produces `True` but `666 is 333 + 333` produces `False`.
John Machin
+2  A: 

There's no hard and fast rule here. Here are some examples where I would use each:

Suppose that I'm interfacing to some function that returns -1 on error and 0 on success. Such functions are pretty common in C, and they crop up in Python frequently when using a library that wraps C functions. In that case, I'd use if x:.

On the other hand, if I'm about to divide by x and I want to make sure that x isn't 0, then I'm going to be explicit and write if x != 0.

As a rough rule of thumb, if I treat x as a bool throughout a function, then I'm likely to use if x: -- even if I can prove that x will be an int. If in the future I decide I want to pass a bool (or some other type!) to the function, I wouldn't need to modify it.

On the other hand, if I'm genuinely using x like an int, then I'm likely to spell out the 0.

Daniel Stutzbach
+1  A: 

It depends on what you want; if x is an integer, they're equivalent, but you should write the code that matches your exact intention.

if x:
    # x is anything that evaluates to a True value
if x != 0:
    # x is anything that is not equal to 0
ΤΖΩΤΖΙΟΥ
A: 

Might I suggest that the amount of bickering over this question is enough to answer it?

Some argue that it "if x" should only be used for Z, others for Y, others for X.

If such a simple statement is able to create such a fuss, to me it is clear that the statement is not clear enough. Write what you mean.

If you want to check that x is equal to 0, then write "if x == 0". If you want to check if x exists, write "if x is not None".

Then there is no confusion, no arguing, no debate.

JS
A: 

If you want to test x in a boolean context:

if x:

More explicit, for x validity (doesn't match empty containers):

if x is not None:

If you want to test strictly in integer context:

if x != 0:

This last one is actually implicitly comparing types.

hcalves