Pythonのfrozensetを使ってimmutableな集合を使う方法

スポンサーリンク

こんにちわ 今日はPythonのfrozenset()メソッドについて説明します。

メソッドに入る前に、frozensetとは何なのかを知っておきましょう。

スポンサーリンク

フロジンセットとは?

フロジンセット(frozenset`)とは、順序や索引を持たない、不変の要素の集まりです。

Pythonの集合が提供するすべての機能を提供しますが、唯一の違いは、フローズンセットはイミュータブルであること、つまり、作成後に変更することができないという事実です。

したがって、簡単に言えば、フローズンセットはイミュータブルなセットなのです。

Python の frozenset() メソッド

Python の frozenset() メソッドは、渡された iterable から要素を取得した新しい frozenset オブジェクトを返します。

iterable` が指定されなかった場合は、空のセットを返します。

注意: 要素はハッシュ化可能でなければならない。

fz = frozenset([iterable])

何も指定しなかった場合、frozenset() メソッドは空の frozenset オブジェクトを fz に返します。

このメソッドがどのように動作するかを理解するために、例を見てみましょう。

# List Initialisation
list1 = [0, 1, 2, 3, 4, 5, 6]
 
fz = frozenset(list1)
print(fz)
 
fz = frozenset()  # empty frozenset
print(fz)
 
print("Type of fz: ", type(fz))

結果は以下の通りです。

frozenset({0, 1, 2, 3, 4, 5, 6})
frozenset()
Type of fz:  <class 'frozenset'>

ここでは、まずリスト (list1) を初期化し、それを iterable として frozenset() メソッドに渡しています。

戻り値として、リストの要素を含むfrozensetオブジェクト(fz)が渡されます。

何も渡さない場合、fzは空のfrozensetオブジェクトになります。

Frozenset初期化

以下の例では、Pythonの frozenset() メソッドにリスト、タプル、セット、辞書などの反復子を渡して、フロジンセットの初期化を行なっています。

# Initialisation
list1 = [1, 2, 3, 4, 5]
 
fz = frozenset(list1)  # from list object
print(fz)
 
fz = frozenset([1, 2, 3, 4, 5])  # from list
print(fz)
 
fz = frozenset({5: 'a', 4: 'B', 3: 'C', 2: 'D', 1: 'E', 0: '0'})# from dict
print(fz)
 
fz = frozenset({'Python', 'Java', 'C', 'C++', 'Kotlin', 'R'})# from set
print(fz)
 
fz = frozenset((17, 55, 26, 90, 75, 34)) # from tuple
print(fz)

結果は以下の通りです。

frozenset({1, 2, 3, 4, 5})
frozenset({1, 2, 3, 4, 5})
frozenset({0, 1, 2, 3, 4, 5})
frozenset({'Java', 'Kotlin', 'Python', 'C', 'R', 'C++'})
frozenset({34, 90, 75, 17, 55, 26})

それぞれのケースについて、対応するイテラブルの要素を含むfrozensetオブジェクトが得られます。

ただし、辞書の場合はキーだけが考慮されることに注意してください。

Pythonのフロジンセットに対する操作

dir()メソッドを使用すると、frozensetオブジェクトに関連するすべてのメソッドの名前を取得することができます

fo = frozenset([1, 2, 3, 4, 5])
 
print(dir(fo))

結果は以下の通りです。

['__and__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__or__', '__rand__', '__reduce__', '__reduce_ex__', '__repr__', '__ror__', '__rsub__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__xor__', 'copy', 'difference', 'intersection', 'isdisjoint', 'issubset', 'issuperset', 'symmetric_difference', 'union']

上記の出力から、add(), remove(), update(), pop() などの様々な関数(要素の変更/更新に使用、セットで使用可能)がないことに注意してください。

これも、フローズンセットはイミュータブル(不変)であるためです。

それでは、フローズンセットで利用可能なメソッドを見てみましょう。

fs = frozenset([1, 12, 23, 45, 67, 89, 100])
 
print("Given Frozenset =", fs)
 
fs_len = len(fs)
print("Length of Frozenset =", fs_len)
 
print("23 in fs? ", 23 in fs)
 
print("23 not in fs? ", 23 not in fs)
 
print("Sets are disjoint? ", fs.isdisjoint(frozenset([10, 5])))
 
print("Set is Subset? ", fs.issubset(set([1, 2, 3, 4, 12, 23, 45, 67, 89, 100])))
 
print("fs is superset? ", fs.issuperset(frozenset({1, 100})))
 
print("Union of sets: ", fs.union(frozenset([-1, -12])))
 
print("Intersection: ", fs.intersection(set([1, 10, 100])))
 
print("Difference: ", fs.difference(frozenset([1, 10, 100])))
 
print("Symmetric difference: ", fs.symmetric_difference(frozenset([1, 10, 100])))
 
fs_copy = fs.copy()
print("Copy of fs: ", fs_copy)

結果は以下の通りです。

Given Frozenset = frozenset({1, 67, 100, 12, 45, 23, 89})
Length of Frozenset = 7
23 in fs?  True
23 not in fs?  False
Sets are disjoint?  True
Set is Subset?  True
fs is superset?  True
Union of sets:  frozenset({1, 67, 100, 12, 45, -12, 23, 89, -1})
Intersection:  frozenset({1, 100})
Difference:  frozenset({67, 12, 45, 23, 89})
Symmetric difference:  frozenset({67, 10, 12, 45, 23, 89})
Copy of fs:  frozenset({1, 67, 100, 12, 45, 23, 89})

ここで

  • len(s): フロジンセットsの長さを返す。
  • x in s: x in s: xがフローゼットsに存在するかどうかを調べる。
  • x が s に含まれない場合。x not in s: xがフローゼットsの要素でなければ真を、そうでなければ偽を返す。
  • isdisjoint(other): 集合が other と共通の要素を持たないとき、真を返します。集合は、その交点が空集合である場合にのみ、不一致となります。
  • issubset(other): issubset(other): other がフロジンセットの要素を含むかどうかをチェックします。
  • issuperset(other): issuperset(other): frozensetに other の要素が含まれるかどうかを調べます。
  • union(*others): union(others):指定されたothersの集合の和を含むフローゼ ンセットを返します。
  • intersection(*others): 渡された他の集合の和集合を含むフローゼンセットを返します。intersection(*others): fs と渡された他の全ての集合に共通する要素を持つフローゼ ンセットを返します。
  • difference(*others): difference(*others): frozenset(fs)に含まれる要素で、他には含まれない要素を持つ新しい frozenset を返します。
  • symmetric_difference(others):新しいフロジンセットを返します。fs と other のどちらかに含まれ、両方に含まれない要素を持つ新しいフローゼット を返します。

Summing Up

今日はここまでです。

Pythonの frozenset() メソッドについて明確に理解していただけたでしょうか。

より詳しい情報は、リファレンスのセクションにあるリンクを参照することをお勧めします。

さらに質問がある場合は、以下にコメントしてください。

参考文献

  • Pythonのfrozenset – ドキュメント。
  • Pythonのタプルとfrozensetの違い – Stack Overflow Question,
    実装におけるセットとfrozensetの違い – Stack Overflow Question, * Set and frozenset difference in implementation – Stack Overflow Question.
タイトルとURLをコピーしました