From what I've seen, the only time None
and False
behave differently is when they're compared to each other (for equality). Am I missing something, or is it ok to use only one or the other as long as you're consistent in your usage? Is there any reason to use one over the other?

- 8,529
- 8
- 37
- 63
-
3One obvious difference is that they mean different things. Use `None` when you want to say "nothing", much like `null` or `nil` might be used in other languages. Use `False` when you want to say "not true". The one you use can make your code more readable, or more confusing. – ChrisGPT was on strike Mar 23 '19 at 11:47
-
,Doesn't "nothing" resolve to false, though? If a list contains nothing, it's `False` as a boolean but `None` as a concept – Alec Mar 23 '19 at 11:49
-
When you have an optional boolean flag. In that case `None` would indicate the flag was not set. – taras Mar 23 '19 at 11:51
-
In Boolean context, `None` is falsy. But that doesn't mean it's _false_. Again, it's in the semantics. What are you trying to tell the programmer? `1` (along with most other things) is truthy. Would you return `1` from a function to indicate a `True` Boolean result? What about `1.5`, which is also truthy? Or the string `"false"` (also truthy). – ChrisGPT was on strike Mar 23 '19 at 11:51
3 Answers
I would emphasize here the semantical difference rather than the behavioral.
Let's consider a couple of functions:
def find_user(criteria):
if is_met(criteria):
return User(...)
return None
# ...vs
def has_email(user):
return bool(user.email)
To me, in the above example, None
means an absence of the value, while False
means the boolean falsity.
An analogy here could be an emergence of the bool
type in C++. Historically, C (ab)used int
for boolean logic, but C++ introduced a dedicated bool
type which makes intentions behind some variables/function signatures clearer.

- 6,348
- 6
- 44
- 90
They are different types. Although, in practice, they behave quite similarly. You could also replace False
with: ""
, []
, (,)
or 0
and everything will mostly work. Python automatically converts your variable into a boolean whenever you pass it to if
, while
, to any boolean operators (eg. or
, and
, etc) or any builtin function expecting a boolean (side note: although or
, and and
do convert your value to boolean while deciding what to return, the end result will be your unconverted value). That's why it's difficult to tell the difference.
However, most developers will consider None
to be similar to a null
value in other languages, which is an error or unitialized value. Whilist False
will usually be considered an expected and fully initialized value. Therefore, it will be easier for most people to read your code if you stick to that convention.
Further elaborating that point, let's consider the C Python implementation. A typical if statement will be converted to the POP_JUMP_IF_FALSE
(or POP_JUMP_IF_TRUE
) instruction. This is how that is implemented:
TARGET(POP_JUMP_IF_FALSE) {
PyObject *cond = POP();
int err;
if (cond == Py_True) {
Py_DECREF(cond);
FAST_DISPATCH();
}
if (cond == Py_False) {
Py_DECREF(cond);
JUMPTO(oparg);
FAST_DISPATCH();
}
err = PyObject_IsTrue(cond);
Py_DECREF(cond);
if (err > 0)
;
else if (err == 0)
JUMPTO(oparg);
else
goto error;
DISPATCH();
}
As you can see, if the value passed to if
is a boolean the interpreter will know what to do right away. Otherwise, it will call PyObject_IsTrue, which will try to convert the object to a bool using any means possible (__bool__
, __nonzero__
, __len__
, and even comparing to None
explicitly).

- 2,377
- 3
- 22
- 32
If you are checking if a value is assigned or exists, you can use None
.
dct = {'key':'value'}
x = dct.get('key', None) # Get the value or get`None if it doesn't exist
def func(...):
if condition:
return Object()
return None
Whereas if you know the value will exist but want to check it's property, use False
if empty_list: #An empty list evaluates to `False`
do something
if not bool_var:
do something
Also bool(None)
evaluates to False

- 8,529
- 8
- 37
- 63

- 20,259
- 5
- 21
- 40
-
3Here, `empty_list is False` _won't_ be true. The `empty_list` isn't the same object as `False`. `is False` is different from "regular" truthiness tests. It's [an object identity comparator](https://stackoverflow.com/q/22885931/354577). – ChrisGPT was on strike Mar 23 '19 at 11:59
-
2I think `if not` is more idiomatic than `if ... is False`, and `.get` returns `None` by default if you don't specify a default argument. Also, as @Chris noted, `is` tests reference equality. – gmds Mar 23 '19 at 11:59
-
-
If the edits looks good! Please consider upvoting @Chris gmds :) – Devesh Kumar Singh May 09 '19 at 17:59