Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

if A vs if A is not None:

Tags:

python

People also ask

Is None vs if not?

Both "if x" and "if x is none" are not the same. If you run the statement "if x:" checks whether x is assigned or not. If you execute the statement "if x is not none", is operator checks whether x is none or not.

How do you know if a list is not None?

Use the is not operator to check if a variable is not None in Python, e.g. if my_var is not None: . The is not operator returns True if the values on the left-hand and right-hand sides don't point to the same object (same location in memory).

Is vs == for None?

is checks to see if the object is the same object, while == just checks if they are equivalent. But since there is only one None , they will always be the same, and is will return True.

Is if not the same as is None Python?

Python is (not) crazy. When you do if val is None , you call the operator is , which checks the identity of x . i.e, if val is value Here, is operator checks whether both the operands refer to the same object or not. None is a singleton in Python and all None values are also the exact same instance.


The statement

if A:

will call A.__bool__() (see Special method names documentation), which was called __nonzero__ in Python 2, and use the return value of that function. Here's the summary:

object.__bool__(self)

Called to implement truth value testing and the built-in operation bool(); should return False or True. When this method is not defined, __len__() is called, if it is defined, and the object is considered true if its result is nonzero. If a class defines neither __len__() nor __bool__(), all its instances are considered true.

On the other hand,

if A is not None:

compares only the reference A with None to see whether it is the same or not.


As written in PEP8:

  • Comparisons to singletons like None should always be done with 'is' or 'is not', never the equality operators.

    Also, beware of writing "if x" when you really mean "if x is not None" -- e.g. when testing whether a variable or argument that defaults to None was set to some other value. The other value might have a type (such as a container) that could be false in a boolean context!


if x: #x is treated True except for all empty data types [],{},(),'',0 False, and None

so it is not same as

if x is not None # which works only on None

A lot of functions return None if there are no appropriate results. For example, an SQLAlchemy query's .first() method returns None if there were no rows in the result. Suppose you were selecting a value that might return 0 and need to know whether it's actually 0 or whether the query had no results at all.

A common idiom is to give a function or method's optional argument the default value of None, and then to test that value being None to see if it was specified. For example:

def spam(eggs=None):
    if eggs is None:
        eggs = retrievefromconfigfile()

compare that to:

def spam(eggs=None):
    if not eggs:
        eggs = retrievefromconfigfile()

In the latter, what happens if you call spam(0) or spam([])? The function would (incorrectly) detect that you hadn't passed in a value for eggs and would compute a default value for you. That's probably not what you want.

Or imagine a method like "return the list of transactions for a given account". If the account does not exist, it might return None. This is different than returning an empty list (which would mean "this account exists but has not recorded transactions).

Finally, back to database stuff. There's a big difference between NULL and an empty string. An empty string typically says "there's a value here, and that value is nothing at all". NULL says "this value hasn't been entered."

In each of those cases, you'd want to use if A is None. You're checking for a specific value - None - not just "any value that happens to cast to False".


They do very different things.

The below checks if A has anything except the values False, [], None, '' and 0. It checks the value of A.

if A:

The below checks if A is a different object than None. It checks and compares the reference (memory address) of A and None.

if A is not None:

UPDATE: Further explanation

Many times the two seem to do the same thing so a lot of people use them interchangeably. The reason the two give the same results is many times by pure coincidence due to optimizations of the interpreter/compiler like interning or something else.

With those optimizations in mind, integers and strings of the same value end up using the same memory space. That probably explains why two separate strings act as if they are the same.

> a = 'test'
> b = 'test'
> a is b
True
> a == b
True

Other things don't behave the same though..

> a = []
> b = []
> a is b
False
> a == b
True

The two lists clearly have their own memory. Surprisingly tuples behave like strings.

> a = ()
> b = ()
> a is b
True
> a == b
True

Probably this is because tuples are guaranteed to not change, thus it makes sense to reuse the same memory.

This shows that you should be extra vigilant on what comparison operator you use. Use is and == depending on what you really want to check. These things can be hard to debug since is reads like prose that we often just skim over it.


Most guides I've seen suggest that you should use

if A:

unless you have a reason to be more specific.

There are some slight differences. There are values other than None that return False, for example empty lists, or 0, so have a think about what it is you're really testing for.


if A: will prove false if A is 0, False, empty string, empty list or None, which can lead to undesired results.