Python进阶编程:编写更高效、优雅的Python代码
上QQ阅读APP看书,第一时间看更新

3.1.4 序列元素统计

在工作过程中,我们经常需要找到一个序列中某个出现次数最多的字符或数字。在Python中是否有函数支持快速寻找字符或数字呢?

collections.Counter类就是专门针对这类问题而设计的,甚至使用most_common()方法即可直接获取答案。

假设要从一个单词列表中找出哪个单词出现频率最高,代码(most_times_exp.py)示例如下:


from collections import Counter
words = [
    'python', 'c++', 'abc', 'php', 'mysql', 'java', 'c#', '.net',
    'ruby', 'lisp', 'python', 'python', 'mongodb', 'hive', 'spark', 'go', 'vb',
    'java', "python", 'c', 'ios', 'sql', 'python', 'java', 'c++',
    'hbase', 'go', "java", 'c++'
]
word_counts = Counter(words)
frequency_num = 2
# 出现频率最高的 frequency_num 个单词
top_three = word_counts.most_common(frequency_num)
print(f'出现频率最高的{frequency_num}个单词是:{top_three}')

执行py文件,输出结果如下:


出现频率最高的2个单词是:[('python', 5), ('java', 4)]

作为输入,Counter对象可以接收任意由可哈希(Hashable)元素构成的序列对象。在底层实现上,一个Counter对象就是一个字典——一个将元素映射为它出现的次数上的字典,示例如下:


print(f"python出现频率:{word_counts['python']}")
print(f"go出现频率:{word_counts['go']}")

如果想手动增加计数,可以简单地使用加法,示例如下:


more_words = ['python','java','go']
for word in more_words:
    word_counts[word] += 1

print(f"python出现频率:{word_counts['python']}")
print(f"go出现频率:{word_counts['go']}")

或者可以使用update()方法,示例如下:


word_counts.update(more_words)

Counter实例的一个鲜为人知的特性是它可以很容易地与数学运算操作相结合,示例如下:


a_obj = Counter(words)
b_obj = Counter(more_words)
print(f'the object of a is:{a_obj}')
print(f'the object of b is:{b_obj}')

c_obj = a_obj + b_obj
print(f'the object of c is:{c_obj}')

d_obj = a_obj - b_obj
print(f'the object of d is:{d_obj}')

Counter对象在需要制表或者计数的场合是非常有用的。建议在解决这类问题的时候应该优先选择它,而不是手动地利用字典去实现。