Python

【Python】オブジェクトをカウントする方法【Counter】

この記事では、Pythonでオブジェクトをカウントする方法を解説します。オブジェクトをカウントするには辞書を使うことで実装できます。また、オブジェクトをカウントするためのクラス collections.Counter() を使うことでより簡単に実装することができます。

オブジェクトをカウントしてみる

リストに格納されているオブジェクトの個数をそれぞれ数えてみましょう。リストの要素を数えるにはcountメソッドが使えます。

items = ['a', 'b', 'c', 'a', 'c', 'a']

a_count = items.count('a')
b_count = items.count('b')
c_count = items.count('c')

print(f'a: {a_count}, b: {b_count}, c: {c_count}')

実行結果

a: 3, b: 1, c: 2

上記の方法では、格納されている要素が事前にわかっていないと行えません。どんな要素が格納されているかわからない場合は辞書を使うことで実装できます。

items = ['a', 'b', 'c', 'a', 'c', 'a']
counter = {}

for item in items:
    if item in counter.keys():
        counter[item] += 1
    else:
        counter[item] = 1

print(counter)

実行結果

{'a': 3, 'b': 1, 'c': 2}

辞書のkeyとして存在しない要素は辞書[要素] = 1で初期化し、keyとして存在していたら辞書[要素] += 1でカウントします。

辞書を使うことでオブジェクトをカウントすることができましたが、collections.Counterクラスを使うことでもっと簡単に実装することができます。

collections.Counterクラス

collectionsモジュールのCounterクラスは、ハッシュ可能なオブジェクトをカウントしてくれる辞書のサブクラスとなっています。collectionsモジュールは標準ライブラリなのでインポートするだけで使用可能です。

import collections

collections.Counter([iterable-or-mapping])

辞書のサブクラスなので同様の処理が可能。

import collections

c = collections.Counter()
c['one'] = 1
c['two'] = 2
c['three'] = 3

c.values()
c.get('one')

初期化

要素を辞書のkeyとし、カウントをvalueとして初期化します。

from collections import Counter

Counter()
# Counter()

Counter('Hello')
# Counter({'l': 2, 'H': 1, 'e': 1, 'o': 1})

Counter(['a', 'a', 'a', 'a', 'b', 'b', 'c'])
# Counter({'a': 4, 'b': 2, 'c': 1})

Counter({'男': 4, '女': 2})
# Counter({'男': 4, '女': 2})

Counter(man=4, woman=2)
# Counter({'man': 4, 'woman': 2})

特徴

Counterクラスには、以下のような特徴があります。

存在しないkeyを指定してもエラーにならない

通常の辞書では存在しないkeyを指定するとKeyErrorが発生しますが、Counterクラスは0を返します。

from collections import Counter

counter = Counter()
print(counter['存在しない要素'])

実行結果

0

要素を削除するにはdel文を使う

valueに0を指定しても要素が削除できるわけではありません。普通にdel文を使って削除しましょう!

from collections import Counter

counter = Counter('Hello')
del counter['l']
print(counter)

counter['H'] = 0
print(counter)

実行結果

Counter({'H': 1, 'e': 1, 'o': 1})
Counter({'e': 1, 'o': 1, 'H': 0})

メソッド

辞書の機能に加えて以下のメソッドが使用可能です。

element()

keyをvalueの数だけ繰り返すイテレータを返します。順序は最初に検出された順です。

from collections import Counter

counter = Counter('mogehoge')
print(list(counter.elements()))

実行結果

['m', 'o', 'o', 'g', 'g', 'e', 'e', 'h']

most_common([n])

(key, value)のタプルを格納したリストを取得できます。並びはカウント数が多いものから格納されています。カウントが同じ場合は、検出された順で格納されます。

from collections import Counter

counter = Counter('mogehoge')
print(counter.most_common())

実行結果

[('o', 2), ('g', 2), ('e', 2), ('m', 1), ('h', 1)]

n引数を指定することで取得するタプルの数を指定できます。

from collections import Counter

counter = Counter('mogehoge')
print(counter.most_common(3))

実行結果

[('o', 2), ('g', 2), ('e', 2)]

subtract([iterable-or-mapping])

引数に指定したイテラブル、または辞書の要素だけカウントが引かれます。

from collections import Counter

# イテラブルオブジェクトの場合
counter = Counter('mogehoge')
counter.subtract('moge')

print(counter)

# 辞書の場合
counter = Counter('mogehoge')
counter.subtract({'m': 3, 'o': 2})

print(counter)

実行結果

Counter({'o': 1, 'g': 1, 'e': 1, 'h': 1, 'm': 0})
Counter({'g': 2, 'e': 2, 'h': 1, 'o': 0, 'm': -2})

まとめ

この記事では、オブジェクトをカウントする方法を解説しました。

オブジェクトをカウントするには辞書を使うことで実装できましたが、collections.Counterクラスを使うことでより簡単にカウントできました。

それでは今回の内容はここまでです。ではまたどこかで〜( ・∀・)ノ

最短3か月でエンジニア転職『DMM WEBCAMP COMMIT』