8.2.7. Set Methods#

Python sets have methods for adding, removing, and checking elements.

Method

Description

.add(x)

Adds a single element

.update(iterable)

Adds multiple elements

.copy()

Returns a shallow copy of the set

.remove(x)

Removes element, raises KeyError if missing

.discard(x)

Removes element, silent if missing

.pop()

Removes and returns an arbitrary element

.clear()

Empties the set

.issubset(s)

Returns True if all elements are in s

.issuperset(s)

Returns True if set contains all of s

.isdisjoint(s)

Returns True if no elements in common

import sys
from pathlib import Path

# Find project root by looking for _config.yml
current = Path.cwd()
for parent in [current, *current.parents]:
    if (parent / '_config.yml').exists():
        project_root = parent
        break
else:
    project_root = Path.cwd().parent.parent

# Add project root to path
sys.path.insert(0, str(project_root))

# Import shared teaching helpers and cell magics
from shared import thinkpython, diagram, jupyturtle, structshape
from shared.download import download

8.2.7.1. Adding elements:#

  • add()

  • update(): adds multiple elements, similar to dict.update().

s = {1, 2, 3}
s.add(4)            # {1, 2, 3, 4}
s.update([5, 6])    # {1, 2, 3, 4, 5, 6}
s
{1, 2, 3, 4, 5, 6}

8.2.7.2. Copy vs aliasing#

Sets are mutable, so assignment shares the same object. Use .copy() when you need an independent set.

a = {1, 2}
b = a               # alias (same object)
c = a.copy()        # separate object

a.add(3)
print("a:", a)
print("b:", b)
print("c:", c)
a: {1, 2, 3}
b: {1, 2, 3}
c: {1, 2}

8.2.7.3. Removing elements:#

  • remove()

  • discard()

  • pop()

  • clear()

s = {1, 2, 3}

s.remove(3)     # raises KeyError if not found
print(s)        # {1, 2}

s.discard(3)    # silent if not found — safer
print(s)        # {1, 2}

s.pop()         # removes and returns an arbitrary element
print(s)        # which item is removed is arbitrary

s.clear()       # empties the set
print(s)        # set()
{1, 2}
{1, 2}
{2}
set()

If you use remove() in a for loop for a set, you may run into an error because Python creates an internal iterator that tracks position inside the set. The moment you call s.remove(), the set’s structure changes and the iterator breaks and raises an error.

The solution to this problem is to iterate over a copy or just use a while loop.

%%expect RuntimeError
s = {1, 2, 3,}
for item in s:
    s.remove(item)
    print(f"Processing {item}")
Processing 1
RuntimeError: Set changed size during iteration
### iterate through copy of the set while modifying the original

for item in s.copy():   # iterate over copy
    s.remove(item)      # modify original safely
    print(f"Processing {item}")
s
Processing 2
Processing 3
set()
# process all items, consuming the set

s = {1, 2, 3}
while s:
    item = s.pop()
    print(f"Processing {item}")
# s is now empty
Processing 1
Processing 2
Processing 3

s.pop() is useful when you want to process and consume a set one element at a time, and you don’t care which element you get. This behavior is different from pop() in list and dict.

list.pop()

dict.pop()

set.pop()

Removes

by index

by key

arbitrary element

Returns

removed value

removed value

removed value

Default arg

index (default -1)

key + optional default

none

If not found

IndexError

KeyError (or default)

KeyError

Predictable?

yes (by index)

yes (by key)

no (arbitrary item)

8.2.7.4. Checking membership:#

s = {1, 2, 3}

print(3 in s)         # True
print(3 not in s)     # False
True
False

8.2.7.5. Subset & Superset:#

a = {1, 2}
b = {1, 2, 3}

a.issubset(b)    # True — all of a is in b
b.issuperset(a)  # True — b contains all of a
a.isdisjoint(b)  # False — they share elements
False

Operator equivalents for subset/superset are often used in real code:

a = {1, 2}
b = {1, 2, 3}

print(a < b)    # proper subset
print(a <= b)   # subset
print(b > a)    # proper superset
print(b >= a)   # superset
print(a <= a)   # True (same set is subset of itself)
print(a < a)    # False (not a proper subset)
True
True
True
True
True
False
### Exercise: Update and Membership Check
# 1. Start with fruits = {"apple", "banana"}.
# 2. Add "cherry" and update with ["banana", "mango"].
# 3. Remove "apple" safely.
# 4. Print whether "mango" is in fruits.
# 5. Print whether {"banana", "cherry"} is a subset of fruits.
### Your code starts here.





### Your code ends here.

Hide code cell source

fruits = {"apple", "banana"}
fruits.add("cherry")
fruits.update(["banana", "mango"])
fruits.discard("apple")

print("mango" in fruits)
print({"banana", "cherry"}.issubset(fruits))
True
True