Python Set Operations

In the last lesson you learned Introduction to Sets. A set is a bag of items with no duplicates and no fixed order. Now comes the part you will actually use day to day. How do you put things into a set? How do you take things out? And how do you ask β€œis this already in here?” That is what this lesson is about.

πŸ€” Why You Need Set Operations

Say you are collecting the email addresses of people who signed up for a newsletter. The same person might submit the form twice. You do not want to email them twice. So you need a place that quietly refuses duplicates. You also want to add new ones fast. And you want to check β€œdid this person already sign up?” in an instant.

A plain list can do some of this. But checking β€œis X already in here?” gets slow as the list grows. A set is built exactly for adding, removing, and fast membership checks. Let us go through each action one at a time.

βž• Adding One Item With add()

The add() method puts a single item into the set. If the item is already there, nothing happens. No error, no duplicate. The set just stays as it is.

Here we start with a few names and add one more.

signups = {"alex", "riya", "arjun"}
signups.add("meera")
print(signups)

Output

{'alex', 'riya', 'arjun', 'meera'}

Remember a set has no fixed order. So the names might print in a different order on your machine. That is normal.

Now watch what happens when we add a name that is already there.

signups = {"alex", "riya", "arjun"}
signups.add("alex")
print(signups)

Output

{'alex', 'riya', 'arjun'}

See, alex was already in the set. So adding it again did nothing. This is the whole point of a set. It keeps things unique for you without you having to check first.

πŸ“₯ Adding Many Items With update()

What if you have a bunch of new items to add at once? Calling add() over and over works, but it is tiring. The update() method takes a whole collection and pours every item into the set in one go.

Here we add three more names from a list.

signups = {"alex", "riya"}
signups.update(["arjun", "meera", "sam"])
print(signups)

Output

{'alex', 'riya', 'arjun', 'meera', 'sam'}

The list ["arjun", "meera", "sam"] got unpacked and each name went in. And just like before, any name that was already present is simply skipped. No duplicates sneak in.

You can pass update() a list, a tuple, another set, or anything you can loop over. So this is your tool for merging new data into an existing set quickly.

Tip

The quick way to remember the two: add() is for one item, update() is for many items.

βž– Removing Items With remove() and discard()

Taking items out has two methods, and the difference between them matters.

remove() deletes an item. But if that item is not in the set, it raises an error and stops your program.

Here we remove a name that exists.

signups = {"alex", "riya", "arjun"}
signups.remove("riya")
print(signups)

Output

{'alex', 'arjun'}

That worked fine because riya was in the set. But now look what happens if we try to remove someone who is not there.

signups = {"alex", "arjun"}
signups.remove("riya")

Output

Traceback (most recent call last):
File "main.py", line 2, in <module>
signups.remove("riya")
KeyError: 'riya'

The program crashed with a KeyError because riya was already gone. Sometimes that is what you want. A loud signal that something is wrong. But often you just want the item gone and you do not care whether it was there.

That is what discard() is for. It removes the item if it is present. And it does nothing if the item is missing. Either way, there is no error.

Here we discard a name that is not in the set, and the program keeps running.

signups = {"alex", "arjun"}
signups.discard("riya")
print(signups)
print("Still running fine.")

Output

{'alex', 'arjun'}
Still running fine.

So the rule is simple. Use discard() when β€œmaybe it is there, maybe not” and you just want it gone. Use remove() when the item really should be there and a missing one means a bug.

Method Item is present Item is missing
remove() Removes it Raises KeyError, stops the program
discard() Removes it Does nothing, no error

πŸ” The Fast in Check

This is where sets really shine. The in keyword asks β€œis this item in the set?” and gives you back True or False.

Here we check whether two people have signed up.

signups = {"alex", "riya", "arjun"}
print("alex" in signups)
print("meera" in signups)

Output

True
False

So "alex" in signups is True because alex is in there. And "meera" in signups is False because she is not.

Now why do people keep saying this is fast? With a list, Python has to walk through the items one by one until it finds a match or reaches the end. If the list has a million items, that is a million checks in the worst case. A set is built differently inside. It can jump almost straight to the answer, no matter how many items it holds. So for β€œis this already in here?” questions, a set is much faster than a list.

That is exactly why our newsletter example wanted a set. Checking β€œdid this email already sign up?” stays fast even with millions of emails.

πŸ“ Counting Items With len()

To find out how many items a set holds, use len(). It is the same function you already use for lists and strings.

Here we count the signups.

signups = {"alex", "riya", "arjun"}
print(len(signups))

Output

3

Because a set never keeps duplicates, len() tells you the count of unique items. That is a handy trick on its own, and it leads us straight to the next part.

🧹 Building a Set From a List to Drop Duplicates

Here is one of the most common real uses of sets. You have a list with repeated values and you want only the unique ones. Just hand the list to set() and it removes every duplicate for you.

Imagine a list of cities people ordered from, with plenty of repeats.

orders = ["delhi", "london", "delhi", "tokyo", "london", "delhi"]
unique_cities = set(orders)
print(unique_cities)
print(len(unique_cities))

Output

{'delhi', 'london', 'tokyo'}
3

The set(orders) call looked at all six entries and kept only the three distinct cities. Then len() told us there are three unique cities.

Once you have the set, you can keep working with it. Add a new city, check if a city is present, count again. Here we take that set and do a few of the operations from this lesson together.

orders = ["delhi", "london", "delhi", "tokyo", "london", "delhi"]
cities = set(orders)
cities.add("paris")
cities.update(["dubai", "tokyo"])
cities.discard("london")
print(cities)
print("tokyo" in cities)
print(len(cities))

Output

{'delhi', 'tokyo', 'paris', 'dubai'}
True
4

Walk through it line by line:

  • set(orders) gave us {"delhi", "london", "tokyo"}, the unique cities.
  • add("paris") put paris in.
  • update(["dubai", "tokyo"]) added dubai. Tokyo was already there, so it was skipped.
  • discard("london") took london out, no error.
  • "tokyo" in cities is True, and len(cities) is 4.

That little block uses almost everything from this lesson in one place.

⚠️ Common Mistakes

A few slip-ups catch people often. Watch for these.

  • Calling remove() on something that might be missing. If you are not sure the item is there, use discard() so your program does not crash.
# ❌ Avoid: crashes if "riya" already left
signups.remove("riya")
# βœ… Good: safe whether or not "riya" is there
signups.discard("riya")
  • Trying to add() many items at once. add() takes one item. If you pass it a list, the whole list becomes one item, which fails because a list cannot live inside a set.
# ❌ Avoid: this raises an error
signups.add(["meera", "sam"])
# βœ… Good: use update() for several items
signups.update(["meera", "sam"])
  • Expecting a set to remember order. Sets have no fixed order, so do not rely on items printing in the order you added them. If order matters, use a list.

  • Forgetting that set() of a list throws away duplicates and order. That is great for counting unique items. But if you needed the original order, sort the result or keep the list around.

βœ… Best Practices

Keep these habits and sets will serve you well.

  • Reach for a set whenever your main question is β€œis this item already in here?”. The fast in check is the reason sets exist.
  • Use discard() as your default remover. Switch to remove() only when a missing item truly means a bug you want to hear about.
  • Wrap a list in set() to get unique values in one line, then len() to count them.
  • Use update() instead of a loop full of add() calls when you are merging many items in.

🧩 What You’ve Learned

A quick recap of the everyday set actions:

  • βœ… add() puts one item in, and quietly ignores it if it is already there.
  • βœ… update() pours in many items at once from a list, tuple, or another set.
  • βœ… remove() deletes an item but raises a KeyError if it is missing.
  • βœ… discard() deletes an item and does nothing if it is missing, so it never crashes.
  • βœ… The in check tells you if an item is present, and it stays fast even on huge sets.
  • βœ… len() counts the items, and set(some_list) drops duplicates so you can count unique values.

Check Your Knowledge

Test what you learned. Pick an answer for each question, then click Check.

  1. 1

    What happens when you call add() with an item that is already in the set?

    Why: Sets keep items unique, so adding an item that already exists does nothing and raises no error.

  2. 2

    You want to remove an item that may or may not be in the set, without any risk of crashing. Which method should you use?

    Why: discard() removes the item if present and does nothing if it is missing, so it never raises an error.

  3. 3

    Why is the in check faster on a set than on a list?

    Why: Sets are built so membership checks do not need to walk through every item, unlike lists.

  4. 4

    What does len(set(["a", "b", "a", "c", "b"])) return?

    Why: set() drops the duplicates, leaving the three unique items a, b, and c, so len() returns 3.

πŸš€ What’s Next?

Now that you can add, remove, and check items in a single set, the next step is combining two sets together. You will see what they share, or join them into one.

Union

Share & Connect