7. Set Yourself Up for Success

A Python set is an unordered collection: the elements of a set do not have a position or order, so you cannot do indexing, slicing, or other sequence-like operations on sets as you would do on, for instance, lists.

Sets in Python mimic mathematical sets: the elements do not repeat. They are especially handy if you have other collections, like lists or tuples, and need to create a new collection of unique values, or the union of two collections, or a a superset (you see, set here is not a coincidence!).

There are many methods (functions) available for a set, but there is also a rich collection of overloaded operators, too. That includes '&', '|', '-', and others, which correspond to their "natural" mathematical analogues. Here are some of the most useful of those overloaded operations:

  • A <= B or A < B: Check if A is a (proper) subset of B
  • A >= B / A > B: Check if A is a (proper) superset of B
  • A | B: Compute the union of two sets
  • A & B: Intersection
  • A - B: Difference
  • A ^ B: Symmetric difference

As usual, you can read more about that in the docs. Below are some examples of several set operations:


In [ ]:
a = set ([1, 2, 3])
b = set ([2, 3, 4])

print ("Set a is", a)
print ("Set b is", b)

print ("Set intersection is", a & b)
print ("Set union is", a | b)
print ("Set symmetric difference is", a ^ b)
print ("Set difference 'a - b' is", a - b)
print ("Set difference 'b - a' is", b - a)

Read-only sets: frozenset. Beside the "normal" set, we have another helpful friend in the set family, the frozenset. A frozenset shares same operations with normal set, except for that fact that they return frozensets. (Huh?)


In [ ]:
c = frozenset ([1, 2, 3])
d = frozenset ([2, 3, 4])

print ("Set c is", c)
print ("Set d is", d)

print ("Set intersection is", c & d)
print ("Set union is", c | d)
print ("Set symmetric difference is", c ^ d)
print ("Set difference 'c - d' is", c - d)
print ("Set difference 'd - c' is", d - c)

The difference between these two types set is that frozenset is immutable while the normal set is mutable. This property gives us the choice to use a frozenset as a key for a dictionary, or to use it when we want to maintain a set of sets. Below you can see an example of a dictionary where sets serve as the key.


In [ ]:
try:
    dict1 = {set([1, 3]): 'set as key'}
    print(dict1)
except Exception as e: 
    print(e)

In [ ]:
try:
    dict2 = {frozenset([1, 3]): 'frozenset as key'}
    print(dict2)
except Exception as e: 
    print(e)

Exercise. One curious thing about sets and frozensets is that you can mix them together in binary operations. What could be the result of such operations? Well, it's not very obvious. Try to think about what you think the operations below should return and what they actually return. If you're interested in diving deeper inside Python, you can look here to get some insights.


In [ ]:
print ("Set intersection between {} and {} is {}".format(a, d, a & d))
print ("Set intersection between {} and {} is {}".format(c, b, c & b))

print ("Set difference between {} and {} is {}".format(a, d, a - d))
print ("Set difference between {} and {} is {}".format(d, a, d - a))