【问题标题】:Casting potential bool to bool in Python, any downsides?在 Python 中将潜在的布尔值转换为布尔值,有什么缺点吗?
【发布时间】:2019-02-24 13:21:11
【问题描述】:

在我的 python 代码中,我将一些 bool() 转换为我知道可能已经是布尔值的变量。这有什么缺点吗? (性能等)

这是我正在使用的函数的基本克隆。

import re
pattern= "[A-Z]\w[\s]+:"
other_cond= "needs_to_be_in_the_text"
def my_func(to_check: str) -> bool:
    res = re.search(pattern, to_check)
    res2 = other_cond in to_check
    return bool(res), bool(res2) # res2 either None or True
# I need boolean returns because later in my code I add all these  
# returned values to a list and use min(my_list) on it. to see if
# there's any false value in there. min() on list with None values causes exception

【问题讨论】:

  • 你的问题太笼统了,你能提供一个示例代码吗?一般来说,显式转换为 bool 看起来很吵,并且会损害可读性
  • 不需要做就不要做。
  • @AzatIbrakov 我添加了我的函数的示例版本。
  • 您的意思是“真实”吗? re.search 的结果肯定不是布尔值。
  • @tobias_k Ups ye 我忘了添加另一部分,我在函数中检查了多个内容,所有返回的内容都进入一个列表,该列表稍后使用 min() 和 None 值导致那里出现异常。

标签: python boolean


【解决方案1】:

通常不需要强制转换为bool(),您可以使用更惯用的if:if not: 语法,但如果有必要并且您想避免bool() 的开销,这是一个相对昂贵的类型构造函数,然后使用更轻量级的方法,例如 operator.truth,一个专门的函数(阅读更多 here)。

Ipython 中 Python 3.6 的计时说明 bool() 相对较慢(但这通常是不必要的微优化):

In [1]: import operator

In [2]: %timeit bool('')
130 ns +- 0.528 ns per loop (mean +- std. dev. of 7 runs, 10000000 loops each)

In [3]: %timeit operator.truth('')
87.9 ns +- 0.0777 ns per loop (mean +- std. dev. of 7 runs, 10000000 loops each)

In [4]: %timeit not not ''
25.3 ns +- 0.176 ns per loop (mean +- std. dev. of 7 runs, 10000000 loops each)

【讨论】:

  • 我重构了我的代码以使用 operator.truth 而不是 bool 强制转换,它似乎工作得很好 - 我想我会坚持这一点,因为它甚至比以前快一点。我还专门测试了它的 None 值,它似乎快了大约 30ns。
【解决方案2】:

取决于“少数”是什么,但一般不会。

当然调用bool 比不调用bool 慢,但这不太可能成为您的瓶颈。


理论上,将变量强制转换为bool 可以触发大对象的垃圾回收,例如:

x = list(range(100000))
x = bool(x)
if x:
    foo()

您是否有第二行可能会影响调用if 主体的时间:转换时,原始列表超出范围并被垃圾收集,当不转换时,原始列表保留在内存中。

我认为这些都是极端情况。

【讨论】:

    【解决方案3】:

    如果不看示例代码就很难发表评论,但转换为 bool 可能会损害代码的可读性。例如,如果语句会隐式检查语句的真实性,因此添加 bool 不会给您任何信息。

    a = [1,2,3]
    
    if a:
        pass
    

    对比包裹在 bool 中,这意味着更多的阅读。

    if bool(a):
        pass
    

    如果您要分配给新变量,则意味着需要跟踪更多内容,并且可能会引入错误,导致已转换变量和原始变量不同步。

     a = [1,2,3]
     a_bool = bool(a)
    
     if a_bool:
          pass # will hit
    
     a = []
    
     if a_bool:
         pass # will still get here, even though you've updated a
    

    如果你不施放,就没有什么可追踪的:

    a = [1,2,3]
    if a:
       pass # will get here
    
    a = []
    
    if a:
        pass  # won't get here.
    

    真实性变量通常在 Python 中被利用,并且使代码更易读。花时间习惯它的工作方式可能比将东西包装在bool 中更好。

    【讨论】:

    • if b: 应该是if a_bool: 吗?
    猜你喜欢
    • 1970-01-01
    • 2018-01-24
    • 2011-01-29
    • 1970-01-01
    • 1970-01-01
    • 2017-03-07
    • 1970-01-01
    • 2021-06-27
    • 1970-01-01
    相关资源
    最近更新 更多