[python] Returning boolean if set is empty

I am struggling to find a more clean way of returning a boolean value if my set is empty at the end of my function

I take the intersection of two sets, and want to return True or False based on if the resulting set is empty.

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

My initial thought was to do

return c is not None

However, in my interpreter I can easily see that statement will return true if c = set([])

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

I've also tried all of the following:

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

Now I've read from the documentation that I can only use and, or, and not with empty sets to deduce a boolean value. So far, the only thing I can come up with is returning not not c

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

I have a feeling there is a much more pythonic way to do this, by I am struggling to find it. I don't want to return the actual set to an if statement because I don't need the values, I just want to know if they intersect.

This question is related to python python-2.7

The answer is


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

If you want to return True for an empty set, then I think it would be clearer to do:

return c == set()

i.e. "c is equal to an empty set".

(Or, for the other way around, return c != set()).

In my opinion, this is more explicit (though less idiomatic) than relying on Python's interpretation of an empty set as False in a boolean context.


not as pythonic as the other answers, but mathematics:

return len(c) == 0

As some comments wondered about the impact len(set) could have on complexity. It is O(1) as shown in the source code given it relies on a variable that tracks the usage of the set.

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

If c is a set then you can check whether it's empty by doing: return not c.

If c is empty then not c will be True.

Otherwise, if c contains any elements not c will be False.


Not as clean as bool(c) but it was an excuse to use ternary.

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

Also using a bit of the same logic there is no need to assign to c unless you are using it for something else.

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

Finally, I would assume you want a True / False value because you are going to perform some sort of boolean test with it. I would recommend skipping the overhead of a function call and definition by simply testing where you need it.

Instead of:

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

Maybe this:

if a.intersection(b):
    # Do something

When you say:

c is not None

You are actually checking if c and None reference the same object. That is what the "is" operator does. In python None is a special null value conventionally meaning you don't have a value available. Sorta like null in c or java. Since python internally only assigns one None value using the "is" operator to check if something is None (think null) works, and it has become the popular style. However this does not have to do with the truth value of the set c, it is checking that c actually is a set rather than a null value.

If you want to check if a set is empty in a conditional statement, it is cast as a boolean in context so you can just say:

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

But if you want it converted to a boolean to be stored away you can simply say:

c = set()
c_has_stuff_in_it = bool(c)