「リストの中に同じ値が何回出てくるか数えたい」「辞書でカウントしようとしたら KeyError が出てしまった」――Pythonを学び始めると、こんな場面に一度は出会いますよね。私も現場でログやCSVを集計するとき、最初は if 文だらけの長いコードを書いていました。
実はこうした「数える」「グループ分けする」処理は、Python標準ライブラリの collectionsモジュール を使うと驚くほどシンプルに書けます。この記事では、特に使用頻度の高い Counter と defaultdict の使い方を、初心者の方にも分かるように実行結果つきで解説します。
collectionsモジュールとは?
collectionsは、Pythonに最初から入っている標準ライブラリで、リストや辞書をさらに便利にした「特殊なデータ型」がまとめられています。インストールは不要で、import するだけで使えます。
- Counter:要素の出現回数を数える辞書
- defaultdict:存在しないキーにも初期値を自動で用意してくれる辞書
- その他:deque(両端キュー)、namedtuple(名前付きタプル)、OrderedDict など
どちらも辞書の仲間なので、辞書の基本を押さえておくと理解がスムーズです。不安な方は先に 辞書(dict)の使い方を解説した記事 を読んでおくのがおすすめです。
Counterの基本的な使い方
辞書で数える場合との比較
まずはCounterを使わずに、普通の辞書で果物の個数を数えてみます。
fruits = ["apple", "banana", "apple", "orange", "banana", "apple"]
counts = {}
for f in fruits:
if f in counts:
counts[f] += 1
else:
counts[f] = 1
print(counts)
# 実行結果: {'apple': 3, 'banana': 2, 'orange': 1}キーがあるかどうかで分岐が必要なので、少し長くなってしまいます。これをCounterで書くと、たった1行です。
Counterで出現回数を数える
from collections import Counter
fruits = ["apple", "banana", "apple", "orange", "banana", "apple"]
c = Counter(fruits)
print(c)
# 実行結果: Counter({'apple': 3, 'banana': 2, 'orange': 1})
print(c["apple"])
# 実行結果: 3
print(c["grape"]) # 存在しないキー
# 実行結果: 0ポイントは、存在しないキーを指定しても KeyError にならず 0 が返る ことです。通常の辞書ではエラーになるので、この違いは覚えておきましょう。なお、1つの値だけを数えたいならリストの count() でも十分です。count() については count関数の使い方を解説した記事 で詳しく紹介しています。
ちなみに、こうした「標準ライブラリで楽に書く」発想は、独学だとなかなか気づけないポイントでもあります。独学で伸び悩んでいると感じたら、現役SEの視点でまとめた プログラミングを学びたい人におすすめのスクール5選 も参考にしてみてください。無料体験で「質問できる環境」を試してみるだけでも、学習効率が大きく変わりますよ。
most_common()でランキングを作る
Counterの一番便利なメソッドが most_common() です。出現回数の多い順に (要素, 回数) のタプルのリストを返してくれます。
print(c.most_common(2))
# 実行結果: [('apple', 3), ('banana', 2)]引数を省略すると、すべての要素を多い順に返します。自分で並び替える方法が気になる方は sortとsortedの違いを解説した記事 もあわせてどうぞ。
文字列や単語を数える
Counterにはリストだけでなく、文字列も渡せます。文字列を渡すと1文字ずつ数えてくれます。
from collections import Counter
# 文字ごとに数える
print(Counter("hello world").most_common(3))
# 実行結果: [('l', 3), ('o', 2), ('h', 1)]
# 単語ごとに数える(split()でリストにしてから渡す)
sentence = "python is fun and python is easy"
print(Counter(sentence.split()).most_common(2))
# 実行結果: [('python', 2), ('is', 2)]update()と足し算・引き算
Counter同士は足し算・引き算ができ、update()で後から要素を追加することもできます。引き算で0以下になった要素は自動的に消えます。
from collections import Counter
c1 = Counter(a=3, b=1)
c2 = Counter(a=1, b=2)
print(c1 + c2)
# 実行結果: Counter({'a': 4, 'b': 3})
print(c1 - c2)
# 実行結果: Counter({'a': 2})
c1.update(["b", "c"])
print(c1)
# 実行結果: Counter({'a': 3, 'b': 2, 'c': 1})合計数を知りたいときは sum(c.values()) と書けばOKです。
defaultdictの基本的な使い方
通常の辞書で起きるKeyError
通常の辞書では、存在しないキーに対していきなり += 1 をするとエラーになります。
d = {}
d["x"] += 1
# 実行結果: KeyError: 'x'defaultdict(int)で自動的に0から始める
defaultdictは、作成時に「初期値を作る関数」を渡しておくと、存在しないキーにアクセスしたときに自動でその初期値を用意してくれます。int を渡すと初期値は 0 になります。
from collections import defaultdict
dd = defaultdict(int)
dd["x"] += 1
print(dd)
# 実行結果: defaultdict(<class 'int'>, {'x': 1})
print(dict(dd)) # 普通の辞書に変換
# 実行結果: {'x': 1}defaultdict(list)でグループ分けする
実務で特に便利なのが list を渡すパターンです。「クラスごとに生徒をまとめる」といったグループ分けが簡単に書けます。
from collections import defaultdict
students = [("A組", "田中"), ("B組", "佐藤"), ("A組", "鈴木"),
("B組", "高橋"), ("C組", "伊藤")]
groups = defaultdict(list)
for cls, name in students:
groups[cls].append(name)
print(dict(groups))
# 実行結果: {'A組': ['田中', '鈴木'], 'B組': ['佐藤', '高橋'], 'C組': ['伊藤']}通常の辞書なら「キーがなければ空のリストを作る」という分岐が必要ですが、defaultdictならその処理が不要になります。
注意点:参照しただけでキーが作られる
defaultdictは「存在しないキーを参照しただけ」でもキーが追加されてしまいます。存在チェックをしたいときは in を使いましょう。
from collections import defaultdict
d2 = defaultdict(int)
print(d2["y"])
# 実行結果: 0
print(len(d2)) # 参照しただけで "y" が追加されている
# 実行結果: 1
print("z" in d2, len(d2)) # in ならキーは増えない
# 実行結果: False 1実践例:ログのレベル別件数を集計する
最後に、私が現場でもよく使う「ログの集計」をCounterで書いてみます。f文字列と組み合わせると、見やすいレポートがすぐに作れます。
from collections import Counter
logs = ["ERROR", "INFO", "WARN", "INFO", "ERROR", "INFO"]
for level, n in Counter(logs).most_common():
print(f"{level}: {n}件")
# 実行結果:
# INFO: 3件
# ERROR: 2件
# WARN: 1件リストを作る段階で条件を絞りたい場合は、リスト内包表記 と組み合わせると、さらにスッキリ書けます。
Counterとdefaultdictの使い分け
- 出現回数を数えたい・ランキングを出したい → Counter
- キーごとにリストや合計をまとめたい → defaultdict(list) / defaultdict(int)
- 1つの値の個数だけ知りたい → リストの count() で十分
もっと効率的にPythonを学びたい人へ
collectionsのような便利な標準ライブラリは、知っているかどうかでコードの量も品質も大きく変わります。ただ、独学だと「そもそもこういう書き方がある」と気づくのが難しいのも事実です。
「未経験からPythonを確実に身につけたい」「分からないところをすぐ質問したい」という方は、マンツーマン指導のスクールを検討してみるのも一つの手です。講師に直接質問できるので、つまずいた箇所をその場で解消でき、転職を見据えたサポートも受けられます。まずは無料カウンセリングで、自分に合うか確かめてみてください。
※本記事には広告(アフィリエイトリンク)を含みます。
Pythonプログラミング|マンツーマンレッスンで初めてをプロに育てる【Python Winner】![]()
スクール選びで迷っている方は、おすすめのプログラミングスクール比較記事 で選び方のポイントもチェックしてみてください。
まとめ
- collectionsはインストール不要の標準ライブラリで、
from collections import Counter, defaultdictで使える - Counterは要素の出現回数を1行で数えられ、存在しないキーは 0 を返す
most_common(n)で出現回数ランキングを簡単に作れる- Counter同士は足し算・引き算、update()での追加ができる
- defaultdict(int) でカウント、defaultdict(list) でグループ分けが KeyError なしで書ける
- defaultdictは参照しただけでキーが追加されるので、存在チェックは in を使う
「数える」「まとめる」処理はデータ分析でも業務システムでも頻繁に登場します。ぜひ手を動かして、Counterとdefaultdictを使いこなしてみてください!
ナノトイラボ 