remove an element from a set and return the set

Question:

I need to iterate over a copy of a set that doesn’t contain a certain element. Until now I’m doing this:

for element in myset:
    if element != myelement:
       ...

But I want something like this, in one line:

for element in myset.copy().remove(myelement):
    ...

Obviously this doesn’t work because the remove method returns None.

Asked By: invalid syntax

||

Answers:

Is this what you’re after?

myset = {1, 2, 3, 4}

for element in myset - {3}:
    print(element)

Output:

1
2
4

You’re correct that remove() returns None upon success instead of the resulting set, it operates in-place without supporting chaining. However, an infix operator like - will be evaluated and return the result. In a sense, you can see set1 - set2 as -(set1, set2), that does return the result or set1.-(set2) if you prefer.

In fact, that method exists:

myset = {1, 2, 3, 4}

for element in myset.difference({3}):
    print(element)

If you look at the Python documentation around sets, they are primarily presented from a functional perspective, expecting you to use infix and prefix operators, as well as function. But a set, like everything in Python, is just an object and has methods that match most (if not all of) the operators.

If you have an expression like set1 - set2, that is a set as well, so you can even call methods on it:

print(({1, 2, 3} - {3, 4, 5}).union({9}))

User @chepner correctly points out in the comments that the method gives you the option of providing other types than just sets as a parameter, for example a tuple:

myset = {1, 2, 3, 4}

for element in myset.difference((3,)):
    print(element)

This may perform slightly better, but keep in mind that this won’t work:

myset = {1, 2, 3, 4}

for element in myset - (3,):
    print(element)

And although the call to .difference() may be faster with a tuple, you should probably test if myset - {3} isn’t faster than myset.difference((3,)) if speed really matters for your code. Especially because what you’re really trying to do probably isn’t as trivial.

Answered By: Grismar

Use the set difference operator.

for element in myset - {myelement}:
    ...

This creates a new set containing the elements of myset that aren’t in {myelement} (namely, myelement itself).

Answered By: chepner

Use filter

for element in filter(lambda x: x != element_to_ignore, element_list):
  do_stuff()
Answered By: Daniel Garcia
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.