bool() 和 operator.truth() 有啥区别?

Posted

技术标签:

【中文标题】bool() 和 operator.truth() 有啥区别?【英文标题】:What are the differences between bool() and operator.truth()?bool() 和 operator.truth() 有什么区别? 【发布时间】:2018-08-07 04:05:45 【问题描述】:

bool()operator.truth() 都测试一个值是 truthy 还是 falsy 并且它们在文档中看起来非常相似,它甚至在 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

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

这个问答是在与ShadowRangerthis question 下的广泛 cmet 和讨论之后产生的。

【问题讨论】:

timeit('b(1)', 'b=bool') 明显比timeit('bool(1)') 快(尽管仍然比truth 慢得多)。查找全局名称 bool 会影响结果。 @khelwood 谢谢,好点,但时差仍然超过两倍,是吗? 是的,truth 仍然肯定比bool 快得多(顺便说一下,比True if ... else False 慢)。 @khelwood 是的,我猜if 语句是高度优化的; truth 的用例是您可以解析像 key=bool 这样的关键字参数的地方 【参考方案1】:

虽然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() 的实现更通用。

因此,如果您的任务对速度非常重要,如果您需要函数(例如解析为sorted() 的键),我建议您使用truth() 而不是bool()。但是,正如khelwood 指出的那样,bool() 偶尔仍然可以更快,例如filter(bool, iterable),因此最好为您的用例确定最佳选择的时间。

当然,如果您不需要函数而只是想测试一个值是 truthy 还是 falsy 您应该使用惯用的 if 或 @ 987654353@ 语句,最快的是 khelwood 和 user2357112 评论。

本问答是在与ShadowRanger 在this question 下进行广泛的交流和讨论之后产生的。

【讨论】:

如果您要进行微优化,以至于您会关心bool 的成本,最好只使用not not x 而不是truth(x) @user2357112 速度只有一半,所以有时可能超过微优化?但是,是的,出现这种情况的上下文是一个关键功能(对于itertools.groupby) 另外,我认为filter 可能会专门针对您将bool 传递给它的情况进行优化。 @Chris_Rands 我对此的了解基本上仅限于我已经说过的内容。 =) 如果它看起来有用,请随意将其中任何一个包含在您的答案中。 @khelwood:是的,filter has a special case for bool that makes it treat as equivalent to passing None(实际上并没有调用回调,而是直接调用了PyObject_IsTrue)。所以例外情况是根本不调用bool;如果实际调用了bool,它总是比等效的truth 慢。 AFAICT,唯一识别这种情况的其他功能是itertools.filterfalse;所有其他itertools(例如takewhile/dropwhile)不提供这种特殊情况。

以上是关于bool() 和 operator.truth() 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

ios中BOOL和bool的区别

ios中BOOL和bool的区别

BOOL和bool的区别

BOOL和bool的区别

Objective-C 中的 bool、Boolean 和 BOOL 之间有啥区别吗?

C中_Bool和bool类型的区别?