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

Chr*_*nds 14 python performance boolean python-2.7 python-3.x

bool()并且operator.truth()都测试一个值是真实的还是虚假的,它们看起来与文档相似,它甚至在truth()文档中说:

这相当于使用bool构造函数.

但是,truth()它的速度bool()是简单测试的两倍(显示的是Python 3.6时序,但2.7类似):

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
Run Code Online (Sandbox Code Playgroud)

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

此问题下与ShadowRanger进行广泛的评论和讨论之后,出现了此问答.

Chr*_*nds 12

虽然bool()并且对主要用例operator.truth() 输出相同的结果,但它们的实现实际上是相当不同的.bool()是一个类或类型构造函数,truth()而是一个窄优化的常规函数​​.

实际上,还存在两个不同之处:1)bool()在没有参数的情况下调用returns Falsetruth()需要参数.2)bool()接受x关键字参数,例如bool(x=1),虽然truth()不带关键字参数.这两个都增加bool()了常规用例的开销.

关键词实现是奇怪的,因为很可能没有人需要它,而且名称x几乎不具描述性.Issue29695涵盖这一点,其实这个问题的影响不只是bool()但其他类,如int()list().但是,从Python 3.7开始,这些关键字参数将被删除,速度应该提高.尽管如此,我测试了最新的Python 3.8分支上的时序,并且bool()比以前更快,但仍然是两倍慢truth(),可能是由于更通用的实现bool().

所以,如果你有个任务,其中速度是非常重要的,我会建议使用truth()bool(),如果你需要的功能(例如解析为一键sorted()).然而,正如凯尔伍德指出的那样,bool()偶尔仍然会更快,例如filter(bool, iterable),所以最好用你的用例来确定最佳选择.

当然,如果你不需要一个函数并且只是想测试一个值是假,你应该使用惯用语ifif not语句,这些是最快的khelwood和user2357112评论.

此问题下与ShadowRanger进行广泛的评论和讨论之后,出现了此问答.

  • @khelwood:是的,[`filter`有一个'bool'特例,使其等同于传递'None'](https://github.com/python/cpython/blob/3.7/Python/bltinmodule。 c#L593)(而不是实际调用回调,而是直接调用`PyObject_IsTrue`)。因此,例外情况是根本没有调用`bool'。如果实际上调用了“ bool”,它总是比等效的“ truth”慢。AFAICT,唯一可以识别这种情况的函数是`itertools.filterfalse`;。所有其他`itertools`(例如`takewhile` /`dropwhile`)都不提供这种特殊情况。 (2认同)