正如其中一条评论所述,您可以简单地使用标签元组而不是它们的列表,这将与模块Counter
中的类一起使用collections
。以下是使用问题中代码的基于列表的方法的方法,以及一些优化,因为您必须处理大量 POS 标签:
from collections import Counter
GROUP_SIZE = 5
counter = Counter()
mylist = []
with open("tags.txt", "r") as tagfile:
tags = (line.strip() for line in tagfile)
try:
while len(mylist) < GROUP_SIZE-1:
mylist.append(tags.next())
except StopIteration:
pass
for tag in tags: # main loop
mylist.pop(0)
mylist.append(tag)
counter.update((tuple(mylist),))
if len(counter) < 1:
print 'too few tags in file'
else:
for tags, count in counter.most_common(10): # top 10
print '{}, count = {:,d}'.format(list(tags), count)
但是,最好也使用deque
模块collections
中的 a 而不是 alist
来执行您正在做的事情,因为前者非常有效,O(1),从任一端追加和弹出,而后者则为 O(n)。他们还使用更少的内存。
除此之外,从 Python v 2.6 开始,它们支持一个maxlen参数,该参数消除了pop()
在达到所需大小后显式结束元素的需要——所以这里有一个基于它们的更高效的版本:
from collections import Counter, deque
GROUP_SIZE = 5
counter = Counter()
mydeque = deque(maxlen=GROUP_SIZE)
with open("tags.txt", "r") as tagfile:
tags = (line.strip() for line in tagfile)
try:
while len(mydeque) < GROUP_SIZE-1:
mydeque.append(tags.next())
except StopIteration:
pass
for tag in tags: # main loop
mydeque.append(tag)
counter.update((tuple(mydeque),))
if len(counter) < 1:
print 'too few tags in file'
else:
for tags, count in counter.most_common(10): # top 10
print '{}, count = {:,d}'.format(list(tags), count)