gal*_*pah 7 python boolean list
将列表转换为bool值的最佳方法是什么?我正在寻找类似的东西:
return eval_bool(my_list)
Run Code Online (Sandbox Code Playgroud)
我有一个自定义容器,我在其中实现了__nonzero__应该像这样工作的方法:
if self.my_list:
return True
return False
Run Code Online (Sandbox Code Playgroud)
但它是否足够pythonic?:)无论如何,我很好奇Python如何解释if语句中列表的值,因为这段代码的工作方式不同:
return my_list == True
Run Code Online (Sandbox Code Playgroud)
J.
Kei*_*ith 20
只需使用:
bool(my_list)
Run Code Online (Sandbox Code Playgroud)
它将其评估为Python"真实性"并返回一个真正的布尔值.
99.9% 的情况下,性能并不重要,因此只需按照Keith 建议的bool(my_list)方式使用即可。
但在性能确实很重要的情况下,其本质bool意味着它实际上相当慢,至少在 CPython 参考解释器上是这样。它必须经过通用函数调用路径、通用构造函数路径、0-1 个参数的通用参数解析(并且在除最新版本的 Python 之外的所有版本中,检查关键字参数),所有这些最终都只是作为引用计数递增在单例上并返回它。
您可以通过微基准测试查看这需要多少成本ipython(在我的 Windows x64 3.6.3 版本上):
In [1]: %%timeit -r5 l = []\n ...: bool(l)\n ...:\n118 ns \xc2\xb1 0.808 ns per loop (mean \xc2\xb1 std. dev. of 5 runs, 10000000 loops each)\nIn [11]: %%timeit -r5 l = [1]\n ...: bool(l)\n ...:\n117 ns \xc2\xb1 0.306 ns per loop (mean \xc2\xb1 std. dev. of 5 runs, 10000000 loops each)\nRun Code Online (Sandbox Code Playgroud)\n\n这可能并不明显,但即使在我相对较弱的笔记本电脑上,仅用 117-118 纳秒来确定真实性也有点太多了。幸运的是,还有其他一些选择。一种是滥用语法来通过专用路径进行真实性评估(从现在开始,我将只测试空的list,两种方式的时间基本相同):
In [3]: %%timeit -r5 l = []\n ...: not not l\n ...:\n25 ns \xc2\xb1 0.289 ns per loop (mean \xc2\xb1 std. dev. of 5 runs, 10000000 loops each)\nRun Code Online (Sandbox Code Playgroud)\n\n这是一个巨大的进步;大约需要五分之一的时间。在 Python 3 上, usingTrue if l else False也可以以相同的速度运行,但它比 Python 2 慢得多not not,其中True和False不是受保护的文字,只是每次都必须动态加载的内置名称。
尽管如此,它并不完美;有时你需要bool一个可调用的,例如通过回调函数(例如 with )将很多值转换为map。幸运的是,该operator模块为您提供了operator.truth;虽然它仍然是一个具有所有开销的可调用对象,但它不是构造函数,它只需要一个参数(不是 0-1),并且它不允许关键字参数,所有这些都会花费CPython 参考解释器上的数量令人惊讶。因此,当您无法使用隐式真实性测试或基于语法的转换not not,并且您仍然需要速度时,operator.truth您是否涵盖了:
In [4]: from operator import truth\n\nIn [5]: %%timeit -r5 l = []\n ...: truth(l)\n ...:\n52.1 ns \xc2\xb1 1.1 ns per loop (mean \xc2\xb1 std. dev. of 5 runs, 10000000 loops each)\nRun Code Online (Sandbox Code Playgroud)\n\n是 的两倍not not,但如果您将它与重复调用它的内置函数一起使用(例如map),则能够将所有工作推送到 C 层,完全避免字节码执行,仍然可以使其成为胜利,并且它的成本仍然远低于bool()其本身的一半。
不过,重申我之前的观点:99.9% 的情况下,性能并不重要,因此只需bool(my_list)按照Keith 建议的方式使用即可。我之所以提到这一点,是因为我曾经遇到过一个场景,其中布尔转换确实是我的代码中最热点的点(通过分析验证),并且使用隐式真实性测试(甚至不进行转换,只是返回调用者list执行的操作if myfunc():)节省了 30%运行时间和退货not not仍然list节省了近 20%。