Pythonには、リストやタプル、辞書などのデータ構造がありますが、集合(set)も非常に便利なデータ型の一つです。集合は重複を許さない要素の集まりですが、さらに集合を「変更不可」にしたデータ型がfrozensetです。この記事では、frozensetの基本的な使い方、setとの違い、そして具体的な応用例について解説します。

frozensetとは?

frozensetは、Pythonの組み込みデータ型の一つで、変更できないセット(イミュータブルな集合)です。通常のsetは要素の追加や削除が可能ですが、frozensetは作成後に変更することができません。これは、リストとタプルの関係に似ており、setが可変であるのに対し、frozensetは不変です。 この不変性(イミュータブル性)により、frozensetは辞書のキーや他の集合の要素として利用できるという利点があります。

frozensetの作成方法

frozensetは、以下のようにfrozenset()関数を使って作成します。リストやタプル、他のセットなど、反復可能なオブジェクトを引数に渡すことで、frozensetを生成することができます。

基本的な作成例

# リストからfrozensetを作成
fs = frozenset([1, 2, 3, 4])
print(fs)  # 出力: frozenset({1, 2, 3, 4})
# タプルからfrozensetを作成
fs2 = frozenset((10, 20, 30))
print(fs2)  # 出力: frozenset({10, 20, 30})
# 既存のセットからfrozensetを作成
s = set([5, 6, 7])
fs3 = frozenset(s)
print(fs3)  # 出力: frozenset({5, 6, 7})

frozensetの特徴は、生成後に要素を追加・削除することができない点です。このため、要素の変更が必要な場合は、まず通常のsetを使用し、その後にfrozensetに変換するという使い方が一般的です。

frozensetの特徴とsetとの違い

frozensetとsetの主な違いは、その変更可能性です。以下は、frozensetとsetの違いを簡単にまとめたものです。

特徴setfrozenset
変更可能性変更可能(ミュータブル)変更不可(イミュータブル)
要素の追加可能不可能
要素の削除可能不可能
辞書のキーとして使用不可能可能
他のsetの要素として使用不可能可能
frozensetの主な用途は、変更したくない集合データを扱う場合や、frozensetを辞書のキーや他の集合の要素として使いたい場合です。例えば、通常のsetは変更可能であるため、辞書のキーとして使うことができませんが、frozensetは不変であるため、辞書のキーとして利用することが可能です。

辞書のキーにfrozensetを使用

# frozensetを辞書のキーに使用
d = {frozenset([1, 2, 3]): "value"}
print(d)  # 出力: {frozenset({1, 2, 3}): 'value'}

このように、frozensetをキーとして使うことで、複数の値の組み合わせに基づく辞書のエントリを作成することが可能です。

frozensetの操作

frozensetは変更不可ですが、通常のsetと同様に集合演算を行うことができます。集合演算には、和集合、積集合、差集合、対称差集合などがあります。

和集合(union)

fs1 = frozenset([1, 2, 3])
fs2 = frozenset([3, 4, 5])
# 和集合(全要素の集合)
result = fs1 | fs2  # または fs1.union(fs2)
print(result)  # 出力: frozenset({1, 2, 3, 4, 5})

積集合(intersection)

# 積集合(共通する要素の集合)
result = fs1 & fs2  # または fs1.intersection(fs2)
print(result)  # 出力: frozenset({3})

差集合(difference)

# 差集合(fs1にあってfs2にない要素)
result = fs1 - fs2  # または fs1.difference(fs2)
print(result)  # 出力: frozenset({1, 2})

対称差集合(symmetric_difference)

# 対称差集合(両方の集合に含まれるが、共通しない要素)
result = fs1 ^ fs2  # または fs1.symmetric_difference(fs2)
print(result)  # 出力: frozenset({1, 2, 4, 5})

frozensetの活用例

frozensetは、シンプルなデータ構造の一部として、特定の場面で便利に使われます。特に、変更不可の集合が必要な場面や、集合を他のデータ構造の一部として扱いたい場合に適しています。

例1: 辞書のキーとしてのfrozenset

以下の例では、複数のアイテムの組み合わせをキーとして使い、それに関連する情報を格納しています。

item_sets = {
    frozenset(['apple', 'banana']): "フルーツセット",
    frozenset(['carrot', 'broccoli']): "野菜セット"
}
print(item_sets[frozenset(['apple', 'banana'])])  # 出力: フルーツセット

例2: セットの中のセット

通常のsetでは、他のsetを要素に含むことはできませんが、frozensetを使用することでセットの中にセットを含めることが可能になります。

inner_set1 = frozenset([1, 2])
inner_set2 = frozenset([3, 4])
outer_set = {inner_set1, inner_set2}
print(outer_set)  # 出力: {frozenset({1, 2}), frozenset({3, 4})}

このように、セットのネスト構造を作ることができます。

まとめ

frozensetは、変更不可なセット型として、Pythonの集合データ構造における重要な役割を果たします。集合データを変更から保護したい場合や、集合を辞書のキーや他の集合の要素として利用したい場合に非常に有効です。また、set と同様に集合演算もサポートしているため、柔軟にデータ操作を行うことができます。 frozensetを使うことで、より堅牢で安全なデータ構造を提供できるようになるため、用途に応じて積極的に活用しましょう。