Python PR

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

記事内に商品プロモーションを含む場合があります

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

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

それでは、オブジェクトをカウントする方法を見ていきましょう。

list.count()でカウントする

リストに格納されているオブジェクトの個数をそれぞれ数えてみましょう。リストに格納されている要素は、list.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

しかし、上記の方法では、リストに格納されている要素が事前に判明していないと数えることができません。また、カウントしたいオブジェクトの種類が多い場合にcountメソッドを何度も呼び出さなければならないのでめちゃくちゃ効率が悪いです。

なので、countメソッドは、1種類のオブジェクトが何個リストに格納されているかカウントしたい場合に使います。

辞書でカウントする

辞書のkeyとしてオブジェクトが格納されていなければ辞書[オブジェクト] = 1で要素を追加します。すでに格納されていれば辞書[オブジェクト] += 1でカウントします。

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}

1回のfor文で複数のオブジェクトをカウントすることができるので複数のオブジェクトをカウントしたい場合はlist.count()よりも効率が良い。

Counterクラスでカウントする

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

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文を使う

value0を指定しても要素が削除できるわけではない。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()

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

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クラスを使うことでより簡単にカウントできました。

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