Python sets have two methods for removing elements: remove() and discard().
They look identical:
colors = {"red", "green", "blue"}
colors.remove("green") # Works
colors.discard("green") # Also works
But watch what happens when the element doesn't exist:
colors = {"red", "blue"}
colors.remove("yellow") # KeyError: 'yellow'
colors.discard("yellow") # Nothing happens. No error.
remove() raises an exception. discard() fails silently.
When to Use Each
Use remove() when missing elements are bugs:
def deactivate_user(active_users, user_id):
active_users.remove(user_id) # Should exist!
# If it doesn't, something's wrong upstream
If user_id isn't in active_users, that's a logic error in your code. You want the exception to surface it.
Use discard() when missing elements are expected:
def cleanup_session(sessions, session_id):
sessions.discard(session_id) # May already be gone
# User might have logged out twice, that's fine
Here, the session might have already been cleaned up. No need to crash over it.
The AI Engineering Context
This pattern appears constantly in data pipelines:
# Processing documents for RAG
processed_ids = set()
for doc in document_stream():
if doc.id in processed_ids:
continue
processed_ids.add(doc.id)
process(doc)
# Cleanup: remove from pending queue
pending_queue.discard(doc.id) # Might not be there
Using discard() here prevents crashes when the same document appears in multiple streams.
The Decision Framework
| Scenario | Use | Because |
|---|---|---|
| Element should exist | remove() |
Missing = bug, surface it |
| Element might exist | discard() |
Missing = expected, ignore it |
| Idempotent operations | discard() |
Safe to call multiple times |
| Strict state management | remove() |
Catch invalid transitions |
One More Option
If you want to know whether removal happened without raising an error, combine in with discard():
if element in my_set:
my_set.discard(element)
print("Removed")
else:
print("Wasn't there")
Though this is rarely necessary—usually you either care (use remove()) or you don't (use discard() and move on).
Which do you default to? Do you prefer loud failures or silent forgiveness?
This is adapted from my upcoming book, Zero to AI Engineer: Python Foundations.
I share excerpts like this on Substack → https://substack.com/@samuelochaba
Top comments (0)