はじめに
皆さんは, Pythonの「frozenset」を知っていますか?
恐らく普段Pythonを使っていてもほとんど目にする機会のない、あるいは全く見たこともないと答える方も多いでしょう。importせずに使えるにも関わらず、そのくらい影が薄いのがfrozensetなのです。
実際に、GoogleとQiitaで「Python frozenset」で検索し、組み込み型のコンテナデータ型とのヒット数を比べてみると、次のような結果になりました。(2023/6/25)
データ型 | Qiita | |
---|---|---|
list | 1,240,000,000 | 27,114 |
tuple | 27,200,000 | 2546 |
dict | 24,700,000 | 7898 |
set | 1,050,000,000 | 22,218 |
frozenset | 271,000 | 93 |
そんなfrozensetを何とかして救ってあげようというのが当記事の目標です。
frozensetの機能と使われない理由
本格的に救う前に(?)まずはfrozensetとは何かについて紹介します。
Pythonの組み込み型には、集合、すなわち被り・順序のないデータのまとまりを示すための型が存在します。「set」と「frozenset」です。この2つは、特定の要素の追加、削除、存在判定が高速なのが特徴です。
その中でも、リストに比べ「存在判定が高速に行える」のは大きな長所で、Qiitaでは過去にこのような記事で取り上げられて話題を呼びました。
Pythonで"in list"から"in set"に変えただけで爆速になった件とその理由
(@kitadakyou氏)
では、「set」と「frozenset」の違いは何でしょうか。それは、ミュータブル (変更可能) か、イミュータブル (変更不可能) か、という点です。setでは要素の追加、削除を高速に行えますが、frozensetでは不可能です。つまり、frozensetはsetの機能を限定したものといえます。
とはいえ、「イミュータブル = ミュータブルの劣化版」というわけではなく、例えば同じコンテナデータ型でイミュータブルであるtupleは、listの機能を限定したものですが、意図せぬ要素の書換を防げる、動作が軽いなどの点から多く使われています。
しかし、frozensetはどうでしょう。setでは、集合型の強みの1つである要素の追加、削除が高速に行えましたが、frozensetではできません。これではただ不便なだけです。
また、要素の存在判定も、setとfrozensetで大きな処理速度の差はありません。
そもそも、setが限られた場面でしか使用されないことや、listと異なり添え字アクセスではないことから、listとは違い誤って書き換えられることも少ないです。
つまり、メインの機能においてfrozensetはsetの完全劣化版ということです。劣化版なら、Qiitaで93件しかヒットしなかったのも納得です。
そんなfrozensetに、setと差別化できるポイントなどあるのでしょうか。
frozensetの使い道(setとの差別化)
この記事を書くにあたり「変更不可能」以外の便利そうな使い道をGoogleに聞きましたが、答えが1件も返ってこなかったので自分で考えました。
重要な差別化ポイント、それは、辞書のキーとして使うことです。
イミュータブルな要素の強みの1つとして、辞書のキーとして使えることが挙げられます。Pythonの辞書はハッシュテーブルが用いられているため、変更不可能な要素でないと使えないようになっています。frozensetを辞書のキーとして使う機会があるかは置いておいて、setとの差別化の1つといえます。
…
他の差別化できる点が1つも思い浮かびませんでした!(謝罪)
おわりに
結論:どうあがいても救えない
もし他のfrozensetの便利な使い道をご存知であれば、ぜひコメント欄で教えてください。
ここまで読んで下さりありがとうございました。