What are the differences between bool() and operator.truth()?

bool() and operator.truth() both test whether a value is truthy or falsy and they seem rather similar from the docs, it even says in the truth() docs that:

This is equivalent to using the bool constructor.

However, truth() is over twice as fast as bool() from a simple test (Python 3.6 timings shown, but 2.7 is similar):

from timeit import timeit
print(timeit('bool(1)', number=10000000))
# 2.180289956042543
print(timeit('truth(1)', setup='from operator import truth', number=10000000))
# 0.7202018899843097

So what are the differences? Should I use truth() instead of bool()?

This Q&A arose after extensive comments and discussion with ShadowRanger under this question.


Although bool() and operator.truth() output the same result for the major uses cases their implementation is actually rather different. bool() is a class or type constructor while truth() is a narrow optimised regular function.

In practical terms, there are also two differences: 1) bool() called with no arguments returns False while truth() requires an argument. 2) bool() accepts an x key word argument, like bool(x=1), while truth() takes no keyword arguments. Both of these add overhead to bool() for the regular use cases.

The key word implementation is odd since likely no-one needs it and the name x is hardly descriptive. Issue29695 covers this, and in fact the issue impacts not just bool() but other classes like int() or list(). However, from Python 3.7 onwards these key word arguments will be removed, and speed should improve. Nonetheless, I tested the timings on the latest Python 3.8 branch, and bool() is faster than before but still over twice as slow as truth(), presumably due to the more generic implementation of bool().

So, if you have a task where speed is of high importance I would recommend using truth() over bool() if you require a function (for example to parse as a key to sorted()). However, as khelwood points out, bool() can still be faster occasionally, such as filter(bool, iterable), so it is probably best to time your use case to be certain of the best option.

Of course, if you don't need a function and simply want to test if a value is truthy or falsy you should use the idiomatic if or if not statements, which are fastest as khelwood and user2357112 commented.

This Q&A arose after extensive comments and discussion with ShadowRanger under this question.