collections.Counter()介绍——快速统计元素出现的次数

  collections.Counter() 是 Python 中一个强大的工具,用于快速统计可迭代对象中元素的出现次数。它属于 collections 模块,返回一个类似字典的子类,键是元素,值是元素的计数。

1、collections.Counter()用法介绍

基本用法

  1. 导入并创建 Counter 对象:
from collections import Counter

# 通过列表、字符串等可迭代对象初始化
c = Counter(['a', 'b', 'a', 'c', 'b', 'a']) 
print(c)  # 输出: Counter({'a': 3, 'b': 2, 'c': 1})

# 统计字符串中字符的出现次数
word_counter = Counter("abracadabra")
print(word_counter)  # 输出: Counter({'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1})
  1. 直接传递键值对或字典:
c = Counter(a=3, b=2)  # 等价于 Counter({'a':3, 'b':2})

常用方法

  • items()
    .items() 方法用于返回元素及其计数的键值对视图,类似于字典的 items()。返回值包含 (元素, 计数) 的元组。

示例:

from collections import Counter

# 创建 Counter 实例
data = ["apple", "banana", "apple", "orange", "banana", "apple"]
counter = Counter(data)

# 使用 .items() 获取键值对
items_view = counter.items()
print(items_view)
# 输出:dict_items([('apple', 3), ('banana', 2), ('orange', 1)])

# 遍历键值对
for item, count in counter.items():
    print(f"{item}: {count}")
# 输出:
# apple: 3
# banana: 2
# orange: 1

# 转换为列表或字典
items_list = list(counter.items())  # [('apple',3), ('banana',2), ('orange',1)]
items_dict = dict(counter.items())  # {'apple':3, 'banana':2, 'orange':1}

统计词频后处理数据:

text = "hello world hello python world"
word_counter = Counter(text.split())

# 筛选出现次数大于1的单词
filtered = {word: count for word, count in word_counter.items() if count > 1}
print(filtered)  # {'hello': 2, 'world': 2}

按计数排序:

# 使用 sorted() 对计数排序(降序)
sorted_items = sorted(counter.items(), key=lambda x: -x[1])
print(sorted_items)  # [('apple',3), ('banana',2), ('orange',1)]
  • elements():
    返回一个迭代器,元素按出现次数重复。
for element in c.elements():
    print(element)  # 输出: a a a b b c
  • most_common(n):
    返回前 n 个最常见元素及其计数。
print(c.most_common(2))  # 输出: [('a', 3), ('b', 2)]
  • update():
    合并其他 Counter 或可迭代对象的计数。
c.update(['a', 'd'])  # c['a'] 变为 4, c['d'] 变为 1
  • subtract():
    减少计数(允许负数)。
c.subtract({'a': 2})  # c['a'] 变为 2

数学运算
加减操作:

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})

其他特性
访问不存在的元素返回 0(而非 KeyError):

print(c['z'])  # 输出: 0

转换为字典:

dict(c)  # 转为普通字典:{'a':3, 'b':2, 'c':1}

应用场景
统计词频:

text = "apple banana orange apple apple banana"
words = text.split()
word_counts = Counter(words)
print(word_counts.most_common(1))  # 输出: [('apple', 3)]

数据分析:

data = [1, 2, 2, 3, 3, 3]
num_counts = Counter(data)
print(num_counts)  # 输出: Counter({3: 3, 2: 2, 1: 1})

快速计数替代手动循环。

注意事项

  • 键必须是可哈希类型(如字符串、数字)。
  • 计数可以为 0 或负数(但 most_common() 会忽略非正数)。

使用 Counter 可以大幅简化统计代码,提升效率。

2、使用实例

  以一道题目为例:


给你一个整数数组 nums 。
如果一组数字 (i,j) 满足 nums[i] == nums[j] 且 i < j ,就可以认为这是一组 好数对 。
返回好数对的数目。

示例 1:
输入:nums = [1,2,3,1,1,3]
输出:4
解释:有 4 组好数对,分别是 (0,3), (0,4), (3,4), (2,5) ,下标从 0 开始


  题目可以通过统计所有数字出现的次数n,该数值产生的对数为Cn2=n∗(n–1)//2C_n^2 = n * (n – 1) // 2Cn2=n(n–1)//2

  1. 解法一

一般想到可以用集合来存放列表中的值,因为集合中的元素是独一无二的,然后对每个数字统计它在列表中出现的次数并累加该数字可产生的对数即可:

    def numIdenticalPairs(nums):
        nums_set = set(nums)
        c = 0
        for each in nums_set:
            n = nums.count(each)
            c += n*(n-1)//2
        return c
  1. 解法二

经过上面的理论学习,发现可以用collections.Counter()来提高效率:

def numIdenticalPairs(nums):
        m = collections.Counter(nums)
        return sum(v * (v - 1) // 2 for k, v in m.items())
### 方法一:使用 `for` 循环和字典 可以通过遍历列表并利用字典来存储每个元素及其对应的出现次数。这种方法简单直观。 ```python def count_elements(lst): counts = {} for element in lst: if element in counts: counts[element] += 1 else: counts[element] = 1 return counts array = [1, 2, 3, 3, 2, 1, 0, 2] result = count_elements(array) print(result) # 输出 {1: 2, 2: 3, 3: 2, 0: 1} ``` 此方法的核心在于通过 `if-else` 条件判断当前元素是否已存在于字典中,如果存在则增加其计数值,否则初始化为 1[^1]。 --- ### 方法二:使用内置模块 `collections.Counter` Python 提供了一个非常方便的工具——`collections.Counter`,它可以快速统计列表中各元素的频率。 ```python from collections import Counter array = [1, 2, 3, 3, 2, 1, 0, 2] counter = Counter(array) print(counter) # 输出 Counter({2: 3, 1: 2, 3: 2, 0: 1}) ``` `Counter` 是一种特殊的字典子类,它会自动计算输入序列中各个元素的数量,并返回一个键值对形式的对象[^5]。 --- ### 方法三:基于 SQL 的分组思路 可以模仿数据库查询中的 `GROUP BY` 思路,先对数据进行排序再按顺序累加相同元素的计数。 ```python def sql_like_count(lst): sorted_lst = sorted(lst) result = [] current_element = None count = 0 for element in sorted_lst: if element != current_element and current_element is not None: result.append((current_element, count)) count = 0 current_element = element count += 1 if current_element is not None: result.append((current_element, count)) return dict(result) array = [1, 2, 3, 3, 2, 1, 0, 2] output = sql_like_count(array) print(output) # 输出 {0: 1, 1: 2, 2: 3, 3: 2} ``` 该算法模拟了 SQL 查询逻辑,类似于执行 `SELECT key, COUNT(*) FROM table GROUP BY key` 的操作[^3]。 --- ### 方法四:列表推导式与集合去重 另一种方式是结合集合去重功能以及列表推导式完成统计工作。 ```python def list_comprehension_method(lst): unique_elements = set(lst) return {element: sum(1 for e in lst if e == element) for element in unique_elements} array = [1, 2, 3, 3, 2, 1, 0, 2] counts = list_comprehension_method(array) print(counts) # 输出 {0: 1, 1: 2, 2: 3, 3: 2} ``` 上述代码首先提取唯一值构成集合,接着针对每一个唯一值重新扫描原列表以累计匹配数量[^4]。 --- ### 方法五:函数化封装 为了提高可读性和复用性,还可以将任意一种方法封装成独立函数调用: ```python def get_counts(lst): from collections import defaultdict counter_dict = defaultdict(int) for item in lst: counter_dict[item] += 1 return dict(counter_dict) example_list = ['apple', 'banana', 'apple', 'orange', 'banana', 'banana'] frequency = get_counts(example_list) print(frequency) # 输出 {'apple': 2, 'banana': 3, 'orange': 1} ``` 这种方式借助于 `defaultdict` 自动处理未定义键的情况,从而简化了传统手动检查的过程。 --- #### 结论 以上介绍了多种实现方案,具体选择取决于实际需求和个人偏好。对于追求效率或者简洁性的场景推荐直接采用 `collections.Counter`;而对于教学演示目的,则更适合展示基础循环结构配合条件分支的操作流程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小白的高手之路

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值