如果set为空,则返回布尔值


97

如果我的函数集结尾为空,我正在努力寻找一种更干净的返回布尔值的方法

我将两个集合相交,并希望返回TrueFalse基于结果集是否为空。

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

我最初的想法是

return c is not None

但是,在我的解释器中,我可以很容易地看到,如果 c = set([])

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

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

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

现在,我已经从文档阅读,我只能用andornot空集来推断一个布尔值。到目前为止,我唯一能想到的就是不返回

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

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


4
如果您将空集bool(set([]))
强制

3
顺便说一句,认真认真地解决了这个问题,这很了不起。
乔纳斯·谢弗(JonasSchäfer)2014年

@JonasWielicki谢谢!欣赏答案-知道那是沿着这些思路的东西。
CB

这个问题将持续5年,并且没有人建议使用isdisjoint。我完全震惊了。
Adirio '19

Answers:


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

bool()会执行类似的操作not not,但在意识形态上更清晰。


7
我反对,bool(...)当你问的时候写作is_empty是晦涩的。我没有表达意图。
tamas.kenez

2
@ tamas.kenez但是,您必须承认,它比not not;)更清晰。(FTR:我已经赞成@gefeis的回答,但是我对OP接受的事物没有影响……)
JonasSchäfer19年

109

不像其他答案那样具有pythonic功能,而是数学功能:

return len(c) == 0

正如一些评论想知道的那样,这len(set)可能会对复杂性产生影响。如源代码中所示,它是O(1),因为它依赖于跟踪集合用法的变量。

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

9
我认为这实际上更好。它使您的意图更加清晰。
arshajii 2014年

4
恐怕len(c)即使c很大,这也必须计算,这对于检查是否为空是不必要的。
米歇尔·德·帕斯卡里斯

1
@Glaedr我相信cpython len的常用数据结构(即列表,集合)为O(1)(即它们在表示长度的数据结构中存储一个变量)
CB

2
^ +1 @CB我对len(c)进行了一些测试,它肯定是表示len的某个变量,因为当集大小改变了惊人的数量级时,运行时差异可忽略不计。
dster77 '17

1
@ dster77我用这两个版本配置了我的代码,与set()(Windows中的python 3.5.2)相比,它的速度明显更快
mathiasfk 17-10-25

23

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

return c == set()

即“c等于空set”。

(或者,反之亦然return c != set())。

在我看来,这比False在布尔值上下文中依赖Python对空集的解释更为明确(尽管较少习惯用法)。


2
实际上,依靠Python的解释是非常可以接受的做法。只要牢记其局限性即可。
火山

17

如果c为set,则可以通过执行以下操作检查它是否为空return not c

如果c为空,那么not cTrue

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


6

当你说:

c is not None

您实际上正在检查c和None是否引用相同的对象。这就是“ is”运算符的作用。在python中,按常规,None是一个特殊的空值,表示您没有可用的值。像c或java中的null之类的sorta。由于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)

1
"""
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()

0

不如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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.