はじめに
いのりさんのエビフライ😋 nikkieです。
Today(※最近) I learnedです。
※本小ネタは使い所が限定的です
目次
- はじめに
- 目次
- サードパーティパッケージを使わずに、挿入順序を保存したsetはできないか?
- dictのfromkeys
- dict.fromkeys()を使った、挿入順序を保存したsetの適用
- 終わりに
サードパーティパッケージを使わずに、挿入順序を保存したsetはできないか?
Pythonのdict
は(3.7から)挿入順序を保存します。
この機能を、挿入順序を保存したsetのように使う小ネタの紹介です(※後述するように限界があります)
なお、過去の記事でboltonsというサードパーティパッケージを紹介しました。
この記事のような縛りをせずに、パッケージ(推しはboltons)を使うのをオススメします
知ったきっかけは、Stack Overflow。
辞書を使うアイデアがこちら:https://stackoverflow.com/a/53657523
見ていきましょう
dict
のfromkeys
dict
にfromkeys
というクラスメソッドがありました!
https://docs.python.org/ja/3/library/stdtypes.html#dict.fromkeys
dict.fromkeys(iterable, value)
は、
iterable からキーを取り、値を value に設定した、新しい辞書を作成します。
value はデフォルトで None となります。
% uv run --python 3.13.0 python >>> dict.fromkeys("abcb") {'a': None, 'b': None, 'c': None}
ここで作っているのは辞書なので、挿入順序が保存されています。
setの場合は、挿入順序ではありません。
>>> set("abcb") {'a', 'c', 'b'}
dict.fromkeys()
を使った、挿入順序を保存したsetの適用
挿入順序を保存、かつ、重複の排除を達成しています。
しかし、挿入順序を保存したsetそのものが得られるわけではありません。
>>> list(set("abcb")) ['a', 'c', 'b'] >>> list(dict.fromkeys("abcb")) # abcbという順序を保存し、かつ、重複が除かれている ['a', 'b', 'c']
挿入順序を保存したsetに近いのはkeys()
メソッド。
上のlist(dict)
はlist(dict.keys())
と同じです。
keys()
メソッドは、「辞書ビューオブジェクト」なるものを返しています。
https://docs.python.org/ja/3/library/stdtypes.html#dictionary-view-objects
このオブジェクトは集合演算をサポートしていますが、単にset
が返るので挿入順序は保存されなくなります(これが先述の「限界」です)
>>> dict.fromkeys("abcb").keys() - set("bd") {'a', 'c'} >>> list(dict.fromkeys("abcb").keys() - set("bd")) ['a', 'c'] >>> dict.fromkeys("abcb").keys() - set("d") # 挿入順序が保存されないsetが返っている {'a', 'c', 'b'} >>> list(dict.fromkeys("abcb").keys() - set("d")) ['a', 'c', 'b']
終わりに
dict.fromkeys()
を知りました。
Python 3.7以降の辞書が挿入順序を保存することを利用して、挿入順序を保存したsetを適用できます。
>>> list(dict.fromkeys("abracadabra")) # 挿入順序を保つ、かつ、重複を除く ['a', 'b', 'r', 'c', 'd']
ただし、挿入順序を保存したsetそのものは得られません。
ユースケースによっては、boltonsをはじめとするサードパーティパッケージをまず検討ください