Kodokon kodokon.com

発展的なデータ構造:タプル、集合、collections

それぞれの必要に合ったデータ構造を選びましょう。イミュータブルなタプル、O(1)で所属を判定できる集合、よくあるパターンのためのCounterとdefaultdictを学びます。

9 分 · 3 問

このレッスンを Kodokon で開く

正しいデータ構造を選ぶことは、可読性とパフォーマンスを一度に決めてしまいます。タプルはイミュータブルなシーケンスです。サイズが固定された、種類の異なる値のレコード(座標、キーと値のペア)に最適です。イミュータブルであることはハッシュ可能であることを意味します(中身もそうであれば)。したがってタプルは辞書のキーや集合の要素になれます。リストにはできないことです。アンパックはコードを表現豊かにします。そして「複数の値を返す」関数は、実際にはタプルを返しているのです。

PYTHON
point = (48.85, 2.35)
lat, lon = point

def min_max(values):
    return min(values), max(values)

low, high = min_max([3, 1, 4, 1, 5])
print(low, high)

distances = {("paris", "lyon"): 465}
print(distances[("paris", "lyon")])
アンパック、複数の値の返却、辞書のキーとしてのタプル

集合は要素の一意性を保証し、平均O(1)で所属を判定します。リストならO(n)です。x in collectionを何千回も調べるループでは、その差はすぐに現れます。集合の演算子(&は積集合、-は差集合、|は和集合)は、入れ子のループに比べて格段の進歩です。二つの識別子のリストを比べて、誰がいなくなり、誰が新しく加わったのかを、二行で書けます。

PYTHON
active = {"ada", "linus", "guido"}
banned = {"linus", "mallory"}

print(active & banned)
print(active - banned)
print(active | banned)

emails = ["a@x.io", "b@x.io", "a@x.io"]
unique = set(emails)
print(len(unique))
集合演算と重複の除去

collectionsモジュールは、日々の二つの必要を満たしてくれます。Counterはイテラブルの中の出現回数を数え、most_common(n)を提供します。数を数えるための辞書を手で書く必要はもうありません。defaultdict(factory)は、存在しない値をその場で作ります。defaultdict(list)は、ループを回すたびにキーの存在を確かめることなく、要素をキーごとにグループ化するための定番の道具です。

PYTHON
from collections import Counter, defaultdict

words = ["go", "py", "go", "rs", "go"]
counts = Counter(words)
print(counts.most_common(2))

groups = defaultdict(list)
pairs = [("fr", "Ada"), ("us", "Lin"), ("fr", "Zoe")]
for country, name in pairs:
    groups[country].append(name)
print(dict(groups))
数えるためのCounter、グループ化するためのdefaultdict

理解度チェック

このレッスンの要点をしっかり覚えているか確認しましょう。

  1. リストとは違い、なぜタプルは辞書のキーになれるのですか?
    • 作成がより速いから
    • イミュータブルであり、したがってハッシュ可能だから
    • 数値しか入れられないから
    • 辞書がリストをタプルに変換するから
  2. 10万個の要素に対して、x in collectionを何千回もテストします。どのデータ構造を選ぶべきですか?
    • リスト。順番に走査する
    • 集合。所属の判定は平均O(1)
    • タプル。リストよりコンパクト
  3. groups = defaultdict(list)のとき、存在しないキーを読み取ると何が起きますか?
    • KeyErrorを投げる
    • 空のリストを返し、そのキーを挿入する
    • 辞書を変更せずにNoneを返す