我有这段代码
text = open("tags.txt", "r")
mylist = []
metalist = []
for line in text:
mylist.append(line)
if len(mylist) == 5:
metalist.append(mylist)
mylist.pop(0)
打开一个文本文件,每行一个POS标记。然后它将前5个POS标签列表添加到mylist,然后将其添加到金属家。然后它向下移动到下一行并创建下一个5个POS标签序列。文本文件总共有大约110k~标签。我需要从金属家找到最常见的POS标签序列。我尝试使用计数器集合,但列表不可清除。解决这个问题的最佳方法是什么?
答案 0 :(得分:1)
正如其中一条评论中所提到的,您可以简单地使用标记元组而不是它们的列表,这些标记将与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)
然而,最好还是使用collections
模块中的deque
而不是list
来做你正在做的事情,因为前者非常有效,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)