推理基础设施 · Python2.6 collections:Counter / defaultdict
02
列表 / 字典操作 · 6 / 6

2.6 collections:Counter / defaultdict

💡 统计 token 频率、按 model 分组请求——你不会想手写循环的

2.6 collections:Counter / defaultdict

Counter:自动计数

from collections import Counter
c = Counter(["a", "b", "a", "c", "a"])
c["a"]              # 3
c.most_common(2)    # [("a", 3), ("b", 1)]

defaultdict:访问不存在的 key 时自动创建

from collections import defaultdict
d = defaultdict(list)
d["qwen"].append(1)        # 不需要先判断 "qwen" 在不在
d["qwen"].append(2)
print(dict(d))             # {"qwen": [1, 2]}

对比 dict

d["qwen"] 在普通 dict 上会抛 KeyError,必须先 if "qwen" in ddefaultdict 直接省掉这步。

示范

from collections import Counter, defaultdict

# 1. 统计每个 model 的请求数
reqs = [
    {"model": "qwen2.5-7b"},
    {"model": "qwen2.5-7b"},
    {"model": "llama3-8b"},
]
counts = Counter(r["model"] for r in reqs)
print(counts)            # Counter({'qwen2.5-7b': 2, 'llama3-8b': 1})
print(counts.most_common(1))   # [('qwen2.5-7b', 2)]

# 2. 按 model 分组
by_model = defaultdict(list)
for r in reqs:
    by_model[r["model"]].append(r)
print(dict(by_model))

✍️ 练习

输入:

log_lines = [
    "INFO  qwen2.5-7b  ok",
    "INFO  llama3-8b   ok",
    "WARN  qwen2.5-7b  slow",
    "INFO  qwen2.5-7b  ok",
    "ERROR llama3-8b   oom",
]

要求:

  1. Counter 数每个 level(INFO / WARN / ERROR)出现几次
  2. defaultdict(list)每个 model 对应的行存成 list

把两个结果都 print 出来。

💡 思路提示

点开看提示
  1. split() 默认按空白分,"INFO qwen2.5-7b ok".split() 得到 ["INFO", "qwen2.5-7b", "ok"]
  2. Counter 接受任何可迭代对象
  3. defaultdict(list) 在访问未存在 key 时自动塞一个空 list

✅ 参考解法

写不出来再打开
from collections import Counter, defaultdict

log_lines = [
    "INFO  qwen2.5-7b  ok",
    "INFO  llama3-8b   ok",
    "WARN  qwen2.5-7b  slow",
    "INFO  qwen2.5-7b  ok",
    "ERROR llama3-8b   oom",
]

levels = Counter(line.split()[0] for line in log_lines)
print(levels)

by_model = defaultdict(list)
for line in log_lines:
    parts = line.split()
    by_model[parts[1]].append(line)
print(dict(by_model))

🔍 进阶思考

Counter 本质是 dict 的子类,Counter.most_common() 是内置的方法。生产代码里几乎所有“按某字段统计 top N”的场景都用它,比手写堆排序清爽太多。