collectionsライブラリ
標準ライブラリのcollectionsには便利なデータ型があります。
namedtuple() | タプル風 | 名前付きフィールドを持つタプルを作成するファクトリ関数 |
---|---|---|
deque | リスト風 | 両端における append や pop を高速に行えるリスト風のコンテナ |
ChainMap | 辞書風 | 複数のマッピングの一つのビューを作成する辞書風のクラス |
Counter | 辞書 | ハッシュ可能なオブジェクトを数え上げる辞書のサブクラス |
OrderedDict | 辞書 | 項目が追加された順序を記憶する辞書のサブクラス |
defaultdict | 辞書 | ファクトリ関数を呼び出して存在しない値を供給する辞書のサブクラス |
UserDict | 辞書 | 辞書のサブクラス化を簡単にする辞書オブジェクトのラッパ |
UserList | リスト | リストのサブクラス化を簡単にするリストオブジェクトのラッパ |
UserString | 文字列 | 文字列のサブクラス化を簡単にする文字列オブジェクトのラッパ |
○Counter (dict型のサブクラス)
頻度のカウントをし、辞書型オブジェクトを作る。
使用例
# -*- coding: utf-8 -*- from collections import Counter text = "あかねさす むらさきのゆき しめのゆき のもりはみずや きみがそでふる" text = text.replace(" ", "") c = Counter(text) #文字をカウントするCounterオブジェクト print(c) #Counter({'き': 4, 'の': 3, 'ゆ': 2,... print(c.most_common(1)) #[('き', 4)] 最頻出の要素を表示
Counterオブジェクトは辞書型のサブクラスなので、辞書と同様の扱いができ、
辞書オブジェクトのメソッドもほぼすべて使える。
存在しない要素に対してはKeyErrorではなく、0を返す。
print(c["き"]) #4 print(c["の"]) #3 print(c["い"]) #0 存在しないときはゼロ print(len(c)) #23
・Counterの生成
c = Counter() # a new, empty counter c = Counter('akasatana') # a new counter from an iterable c = Counter({'あ': 4, 'い': 2}) # a new counter from a mapping c = Counter(あ=4, い=8) # a new counter from keyword args print(c) #Counter({'い': 8, 'あ': 4})
辞書型に追加されたメソッドは3つで、most_common(), elements(), subtract()
・Counter.most_common(n)
nを省くと頻度の多い順に(key, value)のタプルをすべて並べたリストを得る。
引数nを指定すると、頻度順にn個のタプルのリストを得る。
print(c.most_common(2)) #[('き', 4), ('の', 3)] print(c.most_common()[0]) #('き', 4) print(c.most_common()[0][0]) #き print(c.most_common()[0][1]) #4
・Counter.elements()
それぞれの要素をカウントの回数生成するイテレータ
c = Counter(a=4, b=2, c=0, d=-2) >>> sorted(c.elements()) #['a', 'a', 'a', 'a', 'b', 'b']
カウントが0や負の場合は無視される。
・Counter.subtract(iterable)
c = Counter(a=4, b=2, c=0) d = Counter(a=1, b=2, c=3) c.subtract(d) print(c) #Counter({'a': 3, 'b': 0, 'c': -3})
・update(iterable or mapping)メソッドはカウントを置き換えるのではなく、追加。
引数は{"a":1, "b":1}のようなmappingか、
iterableのときは(key, value)対のシーケンスではなく、要素のみのシーケンス。
c = Counter(a=4, b=2, c=0) c.update({"a":1, "b":1}) print(c) #Counter({'a': 5, 'b': 3, 'c': 0}) c.update(["a", "c", "c"]) print(c) #Counter({'a': 6, 'b': 3, 'c': 2})
・数学演算
c = Counter(a=3, b=1) d = Counter(a=1, b=2) c1 = c + d # add two counters together: c[x] + d[x] print(c1) # Counter({'a': 4, 'b': 3}) c2 = c - d # subtract (keeping only positive counts) print(c2) # Counter({'a': 2}) c3 = c & d # intersection: min(c[x], d[x]) print(c3) # Counter({'b': 1, 'a': 1}) c4 = c | d # union: max(c[x], d[x]) print(c4) # Counter({'a': 3, 'b': 2})
・単項加減
c = Counter(a=2, b=-4, c=0) print(c) #Counter({'a': 2, 'c': 0, 'b': -4}) c1 = +c #カウントが正の要素だけ残す print(c1) #Counter({'a': 2}) c2 = -c #カウントの正負を逆にし、正の要素を残す print(c2) #Counter({'b': 4})
・カウントの削除
c = Counter(a=1, b=2, c=3) c["c"] = 0 # カウントを0にするだけで、削除されない print(c) # Counter({'b': 2, 'a': 1, 'c': 0}) c = +c # カウントが正でない要素を削除 print(c) # Counter({'b': 2, 'a': 1}) del c["b"] # delで要素を削除できる print(c) # Counter({'a': 1}) del c # cそのものを削除し、メモリ解放 #print(c) # NameError: name 'c' is not defined
・よくあるパターン
sum(c.values()) # total of all counts c.clear() # reset all counts list(c) # list unique elements set(c) # convert to a set dict(c) # convert to a regular dictionary c.items() # convert to a list of (elem, cnt) pairs Counter(dict(list_of_pairs)) # convert from a list of (elem, cnt) pairs c.most_common()[:-n-1:-1] # n least common elements +c # remove zero and negative counts
deque
リストをキューとして使う。
FIFO(first in first out)として使う。
pop(0)でリスト型の最初の要素を取り出せるが、
python標準のリスト型は左端の要素の追加・取り出し動作が遅いのでcollectionsのdequeを使うのがよい。
dequeはリストの両端での追加、取り出しが高速に実行できる。
from collections import deque q = deque([1, 3, 5]) q.append(7) q.appendleft(-1) print(q) # deque([-1, 1, 3, 5, 7]) print(q.pop()) # 7 print(q.popleft()) # -1 print(q) # deque([1, 3, 5])
他のデータ型についてはそのうち追加