Limitations on what you can put into a set

Documentation

  1. the hash function, the __hash__ method, and hashable
  2. mutable vs. immutable objects

list vs. tuple

A set cannot contain a list, because a list is not hashable. And a list is not hashable because a list is mutable.

s = {[5, 42]}
TypeError: unhashable type: 'list'

But a set can contain a tuple, because a tuple is hashable. And a tuple is hashable because a tuple is immutable.

"""
Create and iterate through a set of tuples.
"""

import sys

corners = {
    (5, 42),  #Fifth Avenue & 42nd Street
    (5, 34),
    (1, 59),
    (2, 72),
    (3, 14)
}

def suffix(n):
    "Return the suffix that makes the int n an ordinal number."
    last2Digits = n % 100
    if 11 <= last2Digits <= 13:
        return "th"
    lastDigit = n % 10
    if lastDigit == 1:
        return "st"
    if lastDigit == 2:
        return "nd"
    if lastDigit == 3:
        return "rd"
    return "th"   #all other numbers

for corner in corners:   #Each corner is a tuple.
    avenue, street = corner
    print(f"{avenue}{suffix(avenue)} Avenue and {street}{suffix(street)} Street")

sys.exit(0)
2nd Avenue and 72nd Street
3rd Avenue and 14th Street
5th Avenue and 34th Street
1st Avenue and 59th Street
5th Avenue and 42nd Street

set vs. frozenset

A set cannot contain a set, because a set is not hashable. And a set is not hashable because a set is mutable.

s = {{5, 42}}
TypeError: unhashable type: 'set'

But a set can contain a frozenset, because a frozenset is hashable. And a frozenset is hashable because a frozenset is immutable.

fs = frozenset({5, 42})   #Call the frozenset function.
s = {fs}
print(s)
{frozenset({42, 5})}
"""
Create and iterate through a set of frozensets.
"""

import sys
import itertools

alliances = {
    frozenset({"United States", "United Kingdom", "Soviet Union", "France"}),
    frozenset({"Germany", "Italy", "Japan"})
}

for alliance in alliances:   #Each alliance is a frozenset.
    print(f"An alliance of {len(alliance)} countries:")
    for i, member in enumerate(alliance, start = 1):
        print(f"{i} {member}")
    print()

for alliance in alliances:
    if {"Germany", "Japan"} <= alliance:   #"is a subset of"
        print("Germany and Japan are allies.")
        break
else:
    print("Germany and Japan are not allies.")

cheaters = set()

for t in itertools.combinations(alliances, 2): #t is a tuple containing 2 frozensets.
    cheaters |= t[0] & t[1]   #Add the members of t[0] & t[1] to cheaters.

if cheaters:   #if cheaters is non-empty
    print()
    print("The following countries belong to more than one alliance:")
    for cheater in cheaters:
        print(cheater)

sys.exit(0)
An alliance of 4 countries:
1 United Kingdom
2 United States
3 France
4 Soviet Union

An alliance of 3 countries:
1 Japan
2 Italy
3 Germany

Germany and Japan are allies.

Add "Italy" to both alliances and see what happens.

Simple examples of itertools.combinations

import sys
import itertools

drugs = {
    "aspirin",
    "alcohol",
    "marijuana",
    "meth"
}

for t in itertools.combinations(drugs, 2):   #t is a tuple containing 2 strings.
    print(f"Testing the interaction between {t[0]} and {t[1]}.")

sys.exit(0)

There are six possible pairs of four drugs:

Testing the interaction between aspirin and meth.
Testing the interaction between aspirin and marijuana.
Testing the interaction between aspirin and alcohol.
Testing the interaction between meth and marijuana.
Testing the interaction between meth and alcohol.
Testing the interaction between marijuana and alcohol.
"""
orgyplanner.py
List all the possible trios of people.
"""

import sys
import itertools

people = {
    "John",
    "Mary",
    "Bill",
    "Sue",
    "Sarah"
}

for t in itertools.combinations(people, 3):   #t is a tuple containing 3 strings.
    print(f"{t[0]}, {t[1]}, and {t[2]}")

sys.exit(0)

There are 10 possible trios:

John, Mary, and Bill
John, Mary, and Sue
John, Mary, and Sarah
John, Bill, and Sue
John, Bill, and Sarah
John, Sue, and Sarah
Mary, Bill, and Sue
Mary, Bill, and Sarah
Mary, Sue, and Sarah
Bill, Sue, and Sarah

Things to try

  1. The keys of a dictionary must be hashable. Therefore the keys can be tuples or frozensets, but not lists or sets.