Python bool()和operator.truth()之间有什么区别?

Python bool()和operator.truth()之间有什么区别?,python,python-3.x,python-2.7,performance,boolean,Python,Python 3.x,Python 2.7,Performance,Boolean,这两种方法都测试一个值是真的还是假的,它们在文档中看起来非常相似,甚至在truth()文档中说: 这相当于使用bool构造函数 但是,从一个简单的测试来看,truth()的速度是bool()的两倍多(显示了Python 3.6计时,但2.7类似): 那么有什么区别呢?我应该使用truth()而不是bool() 虽然bool()和operator.truth()在主要用例中输出相同的结果,但它们的实现实际上是相当不同的,但在与under.进行了广泛的评论和讨论后,出现了此问答bool()是一个类或

这两种方法都测试一个值是真的还是假的,它们在文档中看起来非常相似,甚至在
truth()
文档中说:

这相当于使用bool构造函数

但是,从一个简单的测试来看,
truth()
的速度是
bool()
的两倍多(显示了Python 3.6计时,但2.7类似):

那么有什么区别呢?我应该使用
truth()
而不是
bool()

虽然
bool()
operator.truth()
在主要用例中输出相同的结果,但它们的实现实际上是相当不同的,但在与under.

进行了广泛的评论和讨论后,出现了此问答
bool()
是一个类或类型构造函数,而
truth()
是一个狭义的优化正则函数

实际上,还有两个区别:1)
bool()
调用时不带参数
return
s
False
,而
truth()
需要参数。2)
bool()
接受
x
关键字参数,如
bool(x=1)
,而
truth()
不接受关键字参数。对于常规用例,这两种方法都会增加
bool()
的开销

关键字implementation很奇怪,因为可能没有人需要它,而且名称
x
几乎没有描述性。涵盖了这一点,事实上,该问题不仅影响
bool()
,还影响其他类,如
int()
list()
。但是,从Python3.7开始,这些关键字参数将被删除,速度应该会提高。尽管如此,我还是在最新的Python3.8分支上测试了计时,并且
bool()
比以前快,但仍然比
truth()
慢两倍多,这可能是因为
bool()
的实现更加通用

因此,如果您有一项速度非常重要的任务,我建议您在需要函数时使用
truth()
而不是
bool()
(例如解析为
sorted()
的键)。然而,正如所指出的,
bool()
有时仍然会更快,例如
filter(bool,iterable)
,因此最好对用例进行计时,以确定最佳选项

当然,如果您不需要函数,只是想测试一个值是真是假,那么您应该使用惯用的
if
if not
语句,这两个语句最快,如khelwood和注释所示


这一问答是在与under进行了广泛的评论和讨论后产生的。

timeit('b(1)','b=bool')
明显快于
timeit('bool(1))
(尽管仍然比
truth
慢得多)。查找全局名称
bool
会影响结果。@khelwood谢谢,说得好,但时差仍然超过两倍,是吗?是的,
truth
肯定比
bool
快得多(顺便说一句,如果……否则False)比
True慢得多。@khelwood Yep,我猜
if
语句是高度优化的;
truth
的用例是解析关键字参数,如
key=bool
如果你在进行微优化,考虑到
bool
的成本,最好只使用
而不是x
而不是
truth(x)
@user2357112,这是速度的一半,所以有时候可能不仅仅是微观优化?但是,是的,它产生的背景是作为一个关键功能(对于
itertools.groupby)
而且,我认为
filter
可能会特别优化,以适应将
bool
传递给它的情况。@Chris_Rands我对这方面的知识基本上仅限于我已经说过的内容。=)如果答案有用的话,请随意将其包含在你的答案中。@khelwood:是的,(它不是实际调用回调,而是直接调用
PyObject\u IsTrue
)。因此,例外情况是根本不调用
bool
;如果实际调用了
bool
,它总是比等价的
truth
慢。在AICT中,识别这种情况的唯一其他函数是
itertools.filterfalse
;所有其他
itertools
(例如
takewhile
/
dropwhile
)不提供这种特殊情况。
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