【问题标题】:Returning boolean if set is empty如果 set 为空,则返回布尔值
【发布时间】:2014-02-07 02:23:49
【问题描述】:

如果我的集合在函数结束时为空,我正在努力寻找一种更简洁的方法来返回布尔值

我取两个集合的交集,想根据结果集合是否为空返回TrueFalse

def myfunc(a,b):
    c = a.intersection(b)
    #...return boolean here

我最初的想法是做

return c is not None

但是,在我的解释器中,我可以很容易地看到,如果 c = set([]),该语句将返回 true

>>> c = set([])
>>> c is not None
True

我还尝试了以下所有方法:

>>> c == None
False
>>> c == False
False
>>> c is None
False

现在我从文档中了解到,我只能将 andornot 与空集一起使用来推断布尔值。到目前为止,我唯一能想到的就是返回而不是 c

>>> not not c
False
>>> not c
True

我觉得有一种更 Pythonic 的方法可以做到这一点,因为我正在努力寻找它。我不想将实际集合返回到 if 语句,因为我不需要这些值,我只想知道它们是否相交。

【问题讨论】:

  • 空集被认为是布尔值 False 如果你这样转换它:bool(set([]))
  • 顺便说一句,这个问题做得非常好,非常了不起。
  • @JonasWielicki 谢谢!欣赏答案 - 知道它是这样的。
  • 这个问题要5年了,没有人建议使用isdisjoint。我完全震惊了。

标签: python python-2.7


【解决方案1】:

不像其他答案那样pythonic,而是数学:

return len(c) == 0

正如一些 cmets 想知道len(set) 可能对复杂性产生的影响。它是 O(1),如 source code 所示,因为它依赖于一个跟踪集合使用情况的变量。

static Py_ssize_t
set_len(PyObject *so)
{
    return ((PySetObject *)so)->used;
}

【讨论】:

  • 我认为这实际上更好。它使您的意图更加清晰。
  • 恐怕即使@9​​87654326@ 非常大,这也必须计算len(c),这对于检查是否为空是不必要的。
  • @Glaedr 我相信 cpython len 用于常用数据结构(即列表、集合)是 O(1)(即它们在表示长度的数据结构上存储一个变量)
  • ^ +1 @C.B.我对 len(c) 做了一些测试,它肯定是代表 len 的一些变量,因为当设置大小发生显着数量级变化时,运行时差异可以忽略不计。
  • @dster77 我用两个版本分析了我的代码,与set()(windows 中的python 3.5.2)相比,它明显更快
【解决方案2】:
def myfunc(a,b):
    c = a.intersection(b)
    return bool(c)

bool() 会做一些类似于not not 的事情,但更符合概念和清晰。

【讨论】:

  • 我反对,当你问is_empty 时写bool(...) 是模糊的。我没有表达意图。
  • @tamas.kenez 不过你必须承认,它比not not 更清晰;)。 (FTR:我已经对@gefeis 的回答投了赞成票,但我对 OP 接受的事情没有影响……)
【解决方案3】:

如果您想 return True 获取一个空集,那么我认为这样做会更清楚:

return c == set()

即“c 等于空的set”。

(或者,反过来,return c != set())。

在我看来,这比依赖 Python 在布尔上下文中将空集解释为 False 更明确(尽管不那么惯用)。

【讨论】:

  • 其实,依赖 Python 的解释是非常可以接受的做法。只要牢记其局限性。
【解决方案4】:

如果c 是一个集合,那么您可以通过执行以下操作检查它是否为空:return not c

如果c 为空,则not c 将为True

否则,如果c 包含任何元素not c 将是False

【讨论】:

    【解决方案5】:

    当你说:

    c is not None
    

    您实际上是在检查 c 和 None 是否引用同一个对象。这就是“is”运算符所做的事情。在 python 中 None 是一个特殊的 null 值,通常意味着你没有可用的值。类似于 c 或 java 中的 null 。由于python在内部只​​使用“is”运算符分配一个None值来检查某事是否为None(认为是null)有效,因此它已成为流行的风格。但这与集合 c 的真值无关,它是在检查 c 实际上是一个集合而不是一个空值。

    如果你想在条件语句中检查一个集合是否为空,它在上下文中被转换为布尔值,所以你可以说:

    c = set()
    if c:
       print "it has stuff in it"
    else:
       print "it is empty"
    

    但是,如果您希望将其转换为布尔值以存储起来,您可以简单地说:

    c = set()
    c_has_stuff_in_it = bool(c)
    

    【讨论】:

      【解决方案6】:
      """
      This function check if set is empty or not.
      >>> c = set([])
      >>> set_is_empty(c)
      True
      
      :param some_set: set to check if he empty or not.
      :return True if empty, False otherwise.
      """
      def set_is_empty(some_set):
          return some_set == set()
      

      【讨论】:

        【解决方案7】:

        不如 bool(c) 干净,但它是使用三元的借口。

        def myfunc(a,b):
            return True if a.intersection(b) else False
        

        同样使用一些相同的逻辑,除非您将其用于其他用途,否则无需分配给 c。

        def myfunc(a,b):
            return bool(a.intersection(b))
        

        最后,我假设您想要一个 True / False 值,因为您将使用它执行某种布尔测试。我建议通过简单地测试你需要的地方来跳过函数调用和定义的开销。

        代替:

        if (myfunc(a,b)):
            # Do something
        

        也许是这样的:

        if a.intersection(b):
            # Do something
        

        【讨论】:

          猜你喜欢
          • 2016-05-18
          • 1970-01-01
          • 2010-11-30
          • 2022-12-04
          • 2019-10-07
          • 2020-08-09
          • 1970-01-01
          • 2012-12-06
          • 2019-04-29
          相关资源
          最近更新 更多