set 集合型
- list(リスト)やdict(辞書)と同じく複数の値を管理するコレクションクラス
- 「順序」という概念は無く、各値について個数の概念も無い(あるかないかだけ)
ちょうど数学の「集合」のように扱われるので、集合型という。
集合型独自の関数が最初から用意されていたり、特定の処理をリストと比較して高速に行える。
x in set
: ある値が含まれるかのチェックが速いs & t
: 2つの集合に共通して含まれる要素s ^ t
: どちらか一方だけに含まれる要素- and more
2つの集合が1つでも共通要素を持つかのチェック
全ての共通要素を得る必要は無く、1つでもあるか無いかだけ調べたい場合、どのような書き方が速いか。
以下のサイトで、詳しく説明されている。
Test if lists share any items in python - Stack Overflow
- intersection
- 他と比べてやや遅い
- generator expression
- 共通要素の存在確率が高い場合、最も速くなり得る
- 一方、確率が低い場合、かなり遅い
- disjoint
- おすすめ
- 安定して速い
generator expressionを除いては、遅くとも1回あたり0.2~0.3ミリ秒くらいなので、チェック回数が数万程度ならそこまで気にするものでもないだろう。
1.intersection
if a & b: pass # 何らかの処理
aとbの共通要素を求めてから、要素が空かどうか調べる。
- 素直でコードの意図がわかりやすい
- 無駄な処理が発生する
- 調べるのは最初の1個が見つかった時点まででいいのに、最後まで調べてしまう
- 返値に新しいsetを生成する
2.generator expression
if any(i in b for i in a): pass # 何らかの処理
- any()内にリスト内包表記を使用する
- 最初にTrueと評価される値が存在した時点で処理が止められるので、無駄な比較が発生しない
- 一方、python上で
for .. in ..
ループを回すので、組み込みと比べて速度的に不利 - 共通要素が存在する確率が高い場合、最も速かったりする(ピーキーで運任せ)
3.disjoint
if not a.isdisjoint(b): pass # 何らかの処理
「2つの集合が共通要素を持たない」ことを調べる関数isdisjoint()
を利用する
- disjointとは、「互いに素」という意味
- ここまで目的に適合する関数があるなら素直に使っとけって話ですよね
- Stack Overflow見るまで知らなかった……
- ただ、そこまで圧倒的に速いわけでも無い