PythonでSetのSetを作成する

PythonでSetのSetを作成しようとするとエラーになります。

my_set = set()
my_set.add({1, 2, 3})
# => TypeError: unhashable type: 'set'

Pythonでは、Setの各要素はハッシュ可能(hashable)でなければいけません。 Pythonの組み込み型でハッシュ可能なのは、int, str, tuple, frozensetです。list. dict, setはunhashableハッシュ不可能(unhashable)です。

ハッシュ可能についてはこちらの記事を参考にしました。

qiita.com

frozensetを使う

pythonでsetのsetを作成するには、frozensetを使用します。frozensetはイミュータッブルでハッシュ可能な型です。

my_set = set()

my_set.add(frozenset({1, 2, 3}))
my_set.add(frozenset({4, 5}))

print(my_set)
#=> {frozenset({1, 2, 3}), frozenset({4, 5})}

エラーなく動作しました。

もう少し挙動を確認してみます。

my_set = set()

# setにsetを追加する
my_set.add(frozenset({1, 2, 3}))
my_set.add(frozenset({1, 2}))
my_set.add(frozenset({2, 1}))  # 集合としては1つ上と同じ
my_set.add(frozenset({5, 4, 3}))
my_set.add(frozenset({4, 3, 5, 3, 4}))  # 集合としては1つ上と同じ
my_set.add(frozenset({4}))
my_set.add(frozenset({10, 2, 4, 7, 2}))
# addの回数は7回

print(len(my_set))
# => 5

print(my_set)
# => {frozenset({1, 2}), frozenset({10, 2, 4, 7}), frozenset({3, 4, 5}), frozenset({1, 2, 3}), frozenset({4})}
# {1, 2} と {2, 1} は同一のものなので、setには片方が登録されている
# {5, 4, 3} と {5, 4, 3, 3, 4} は同一のものなので、setには片方が登録されている

print({1, 2} in my_set)
# => True
# setとの比較は可能

print({3, 5, 4} in my_set)
# => True
# {3, 4, 5}と同一のものとして判定される

print({2} in my_set)
# => False
# 2が含まれる要素もあるが、my_setの要素としては一致しないのでFalseとなる

以上で、setのsetの作成と、動作確認ができました。