この記事では、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文を使う
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
クラスを使うことでより簡単にカウントできました。
それでは今回の内容はここまでです。ではまたどこかで〜( ・∀・)ノ