文字列のリストから単語の出現頻度をカウントする、といったケースはしばしばあるかと思います。
dictやdefaultdictで実装すると初期値0の設定が必要だったりしてちょっとめんどくさいです。
words = ["dog", "cat", "dog", "dog", "mouse", "cat"] # dictの場合 counter = {} for w in words: if w in counter: counter[w] += 1 else: counter[w] = 1 # defaultdictの場合 from collections import defaultdict counter = defaultdict(lambda: 0) for w in words: counter[w] += 1
collections.Counterを使うとワンラインでカウントできます。
counter = Counter(words) print(counter) # Counter({'dog': 3, 'cat': 2, 'mouse': 1})
引数無しでもCounterオブジェクトを生成できます。dict同様にキーでアクセスでき、初期値0としてカウントアップできます。
counter = Counter() for w in words: if w == "dog": counter["dog"] += 1 else: counter["others"] += 1 print(counter) # Counter({'dog': 3, 'others': 3})
無い要素にアクセスした場合は0が返ります。
print(counter["rabbit"]) # 0
文字列だけではなく数値やタプルもキーにできます。
counter = Counter([1, 2, 1, 3, 4, 1]) print(counter) # Counter({1: 3, 2: 1, 3: 1, 4: 1}) counter = Counter([(1, 2), (1, 3), (1, 2), (2, 4)]) print(counter) # Counter({(1, 2): 2, (1, 3): 1, (2, 4): 1})
Counterオブジェクト同士の加算・減算もできます。"-"オペレータではゼロや負値になりませんが、subtractメソッドを使うとゼロや負になりえます。
counter_plus = counter1 + counter2 print(counter_plus) # Counter({'dog': 4, 'cat': 2, 'mouse': 1}) counter_minus = counter1 - counter2 print(counter_minus) # Counter({'dog': 2}) counter1.subtract(counter2) print(counter1) # Counter({'dog': 2, 'cat': 0, 'mouse': -1})
dict型への変換も組み込み関数dictでできます。
counter = Counter(words) counter_dict = dict(counter) print(type(counter_dict)) # <class 'dict'> print(counter_dict) # {'dog': 3, 'cat': 2, 'mouse': 1}
ちょっとした実装で役立ちそうなクラスを紹介しました。