Python中使用Counter实现简单的计数器

在 Python 中可以使用 collections 内置模块下的 Counter 来实现简单的统计功能

统计列表中的元素

1
2
3
4
5
6
7
8
import collections
import random

l = [chr(random.randint(97, 102)) for i in range(20)]
print(l)

result = collections.Counter(l)
print(result)

执行结果为:

1
2
['f', 'f', 'b', 'e', 'e', 'c', 'd', 'f', 'b', 'f', 'c', 'd', 'c', 'f', 'e', 'c', 'e', 'f', 'e', 'e']
Counter({'f': 6, 'e': 6, 'c': 4, 'd': 2, 'b': 2})

统计文件中单词出现的频率

1
2
3
4
5
6
7
8
import collections
import re
f = open('/etc/apache2/extra/httpd-ssl.conf', 'r')

txt = re.split('\W+', f.read())
s = collections.Counter(txt)

print(s)

执行结果为:

1
2
Counter({'the': 93, 'to': 39, 'and': 32, 'for': 31, 'SSL': 29, 'is': 26, 'a': 21, 'of': 21, 'private': 20, 'in': 18, 'you': 17, 'server': 17, 'file': 16, 'apache2': 16, 'be': 16, '1': 16, 'etc': 15, 'certificate': 15, 'this': 14, 'as': 13, 'This': 13, '0': 13, 'or': 13, 'use': 12, 'client': 10, 'that': 10, 'when': 10, 'can': 10, 'are': 9, 'mod_ssl': 9, 'ciphers': 9, 'CA': 8, 'on': 8, 'one': 8, '2': 8, 'an': 7, 'crt': 7, 'standard': 7, 'TLS': 7, 'The': 7, 'directives': 7, 'ssl': 7, 'Use': 7, 'only': 7, 'o': 7, 'shutdown': 7, 'dev': 7, 'all': 6, 'more': 6, 'close': 6, 'used': 6, 'not': 6, 'which': 6, 'notify': 6, 'key': 6, 'default': 6, 'certificates': 6, 'alert': 6, 'var': 6, 'also': 6, 'should': 5, 'OpenSSL': 5, 'SSLv3': 5, 'PEM': 5, 'encoded': 5, 'clients': 5, 'random': 5, 'OCSP': 5, 'containing': 5, 'with': 5, 'connection': 5, 'from': 5, 'SSLCertificateFile': 5, 'user': 5, 'both': 5, 'parallel': 4, 'variables': 4, 'usually': 4, 'at': 4, 'Note': 4, 'HIGH': 4, 'configured': 4, 
......

以上方法在读取文件的时候, 采用了读取全部内容到内存的方法, 如果文件体积较大, 会对内存造成较大压力, 可以通过如下这种迭代的用法实现相同的功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import collections
import re
f = open('/etc/apache2/extra/httpd-ssl.conf', 'r')

# 创建一个空集合对象
s = collections.Counter()

# 迭代文件中的每一行
for line in f:
# 将每行内容进行按单词的切割, 在切割之前去掉每行字符串的首位空格以及换行
res = re.split('\W+', line.strip())

# 字符串切割后, 拿到 res 列表, 循环迭代它
for word in res:
# 如果不是空字符的话就在集合中将该键出现的次数+1
if word:
s[word] += 1

print(s)

执行结果与上面相同

统计后找出前三个元素

在 counter 对象中, 还有一个功能可以帮我们取出指定的元素

1
2
3
4
5
6
7
8
9
10
11
12
import collections
import re
f = open('/etc/apache2/extra/httpd-ssl.conf', 'r')

s = collections.Counter()
for line in f:
res = re.split('\W+', line.strip())
for word in res:
if word:
s[word] += 1

print(s.most_common(3))

执行结果为:

1
[('the', 93), ('to', 39), ('and', 32)]