set.pop()
Remove and return an arbitrary element from the set. The element choice is not defined — treat pop as random for portability.
Common call
while s: process(s.pop())
Returns
the removed element — not None
Replaces
the manual `next(iter(s))` + discard pattern
Watch out
element choice is UNDEFINED — do not rely on any particular order
set.pop()
→ Any
Demo
Live evaluation
Try:
Inputs
setsetstarting set (comma-separated)
Output
{'a', 'b', 'c'}.pop()
'a'
pop removes and returns ONE element — but the demo shows only the REMAINING set state so you can see the mutation. In real code the returned element is what you work with. WHICH element gets popped is implementation-defined; treat it as arbitrary. Empty set raises KeyError.
Common patterns
Drain a set for processing
Process every element exactly once without holding an iterator.
while pending: item = pending.pop() process(item)
Get and remove any element
When you need one and do not care which.
representative = candidates.pop() # any of them works
Guard the empty case
Empty set raises KeyError.
item = s.pop() if s else default
Examples
1. Basic
s = {1, 2, 3}
s.pop()
Returns
some element — say 12. State after pop
s = {1, 2, 3}
s.pop()
s
Returns
set with 2 elements — which one depends on impl3. Empty raises
set().pop()
Returns
KeyError: 'pop from an empty set'4. Drain in a loop
s = {"a", "b", "c"}
out = []
while s: out.append(s.pop())
out
Returns
all three elements in some order5. One element case
s = {42}
s.pop()
Returns
42 # the only choicePitfalls
1. The popped element is UNDEFINED — do not rely on order
Sets are unordered. Python does not guarantee which element pop returns. It may look consistent for small sets in one Python version and change in the next. Code that assumes an order will break.
Assumed order
s = {1, 2, 3} first = s.pop() assert first == 1 # NOT guaranteed
may pass today, fail tomorrow
Sort first
first = min(s) s.discard(first)
deterministic
2. Empty set raises KeyError
Not None, not a sentinel — a KeyError with the message "pop from an empty set". Guard with truthiness or catch.
Blows up
while True: x = s.pop() ...
KeyError: 'pop from an empty set' at end
Truthy guard
while s: x = s.pop() ...
stops cleanly
3. pop() has NO index argument — unlike list.pop
list.pop(0) removes the first item; list.pop() removes the last. set.pop() takes NO arguments — the concept of "position" does not apply to sets.
Wrong shape
s.pop(0)
TypeError: pop() takes no arguments (1 given)
Right shape
s.pop()
some element
4. set.pop is not a queue or stack
Because element choice is undefined, you cannot use set.pop as FIFO or LIFO. If order matters, use a list (as a stack) or collections.deque (as a queue).
Assumed LIFO
s = {"first", "second", "third"} assert s.pop() == "third"
may fail — order not guaranteed
Use a stack/queue
stack = ["first", "second", "third"] assert stack.pop() == "third"
guaranteed
When to use
Use it
- Draining a set for one-shot processing (drain-and-empty loops)
- Getting any single element when the choice does not matter
- Building a worklist algorithm on top of a set
- Convert set to worklist when order does not matter
Reach for something else
- You need a SPECIFIC element → set.remove or set.discard
- Order matters (FIFO / LIFO / sorted) → list, deque, or heapq
- You want to keep the element in the set → iterate instead
- You do not want an exception on empty → guard first, or use set.discard on a chosen element
Notes
Complexity
O(1) amortized — Python removes an arbitrary bucket entry
Return
The removed element; set is mutated in place
CPython impl
Objects/setobject.c :: set_pop
Memory
In-place; no allocation
Thread-safe
Not safe under concurrent mutation of the same set
FAQ
Undefined — Python does not guarantee any particular element. In CPython it happens to be the first bucket found in the hash table, which is neither insertion nor sort order. If order matters, sort or index a list instead.
History
2.3
set type added; pop has been the arbitrary-remove method from the start.