Python中列表的bool值

时间:2012-03-24 08:33:07

标签: python list boolean

将列表转换为bool值的最佳方法是什么?我正在寻找类似的东西:

return eval_bool(my_list)

我有一个自定义容器,我在其中实现了__nonzero__方法,它应该像这样工作:

if self.my_list:
    return True
return False

但它是否足够pythonic? :)无论如何,我很好奇Python如何解释if语句中列表的值,因为这段代码的工作方式不同:

return my_list == True

学家

4 个答案:

答案 0 :(得分:17)

只需使用:

bool(my_list)

将其评估为Python“真实性”并返回一个真实的布尔值。

答案 1 :(得分:1)

如果len(my_list) == 0返回false,则为true。写完是pythonic:

return len(my_list)

虽然它以整数形式返回,但对于非零长度计算为true,否则为false。

答案 2 :(得分:0)

您可以使用三元“ if”运算符。谷歌表示从2.5开始就支持。

foo = True if your_list else False

答案 3 :(得分:0)

99.9%的时间中,性能无关紧要,因此只需将bool(my_list)用作Keith suggests

在性能很重要的情况下,bool的性质意味着它实际上相当慢,至少在CPython参考解释器上是如此。它必须经过通用的函数调用路径,通用的构造函数路径,针对0-1个参数的通用参数解析(并在all but the most recent versions of Python中检查关键字参数),所有这些最终最终只能作为单例的引用计数递增并退回。

使用ipython微基准测试(在我的Windows x64 3.6.3构建中),您会看到多少费用:

In [1]: %%timeit -r5 l = []
   ...: bool(l)
   ...:
118 ns ± 0.808 ns per loop (mean ± std. dev. of 5 runs, 10000000 loops each)
In [11]: %%timeit -r5 l = [1]
    ...: bool(l)
    ...:
117 ns ± 0.306 ns per loop (mean ± std. dev. of 5 runs, 10000000 loops each)

这可能并不明显,但是即使在我相对较弱的笔记本电脑上,仅117-118纳秒就可以确定真相。幸运的是,还有其他两种选择。一种是滥用语法,以通过专用路径进行真实性评估(从现在开始,我将只测试空的list,这两种方式的时间基本相同):

In [3]: %%timeit -r5 l = []
   ...: not not l
   ...:
25 ns ± 0.289 ns per loop (mean ± std. dev. of 5 runs, 10000000 loops each)

这是一个巨大的进步;大约需要五分之一的时间。在Python 3上,使用True if l else False的速度也相同,但比Python 2上的not not慢得多,在Python 2上,TrueFalse并不是受保护的文字,只是构建而已-in每次必须动态加载的名称。

仍然,这并不完美;有时您需要可调用,例如通过回调函数(例如,使用bool)将大量值转换为map。幸运的是,the operator module覆盖了with operator.truth;尽管它仍然是可调用的,并且产生了所有开销,但它不是构造函数,它需要精确地 一个参数(不是0-1),并且不允许关键字参数,所有这些参数的成本都是CPython参考解释器上的数量惊人。因此,当您无法使用not not进行隐式真实性测试或基于语法的转换而仍然需要速度时,operator.truth可以满足您的需求:

In [4]: from operator import truth

In [5]: %%timeit -r5 l = []
   ...: truth(l)
   ...:
52.1 ns ± 1.1 ns per loop (mean ± std. dev. of 5 runs, 10000000 loops each)

not not的两倍,但是如果您将它与反复调用它的内置函数一起使用(例如map),则能够将所有工作推到C层,避免字节完全执行代码,仍然可以取胜,而且成本仍然比bool()本身低一半。

不过我要重申一点: 99.9%的时间,性能并不重要,因此只需将bool(my_list)用作Keith suggests我之所以仅提及这一点,是因为我曾经遇到过这样一种情况:布尔转换确实是我的代码中最热的点(通过概要分析进行了验证),并且使用了隐式真实性测试(甚至不进行转换,只是在调用者返回时返回list if myfunc():)减少了30%的运行时间,而返回的not not中的list节省了近20%。