我正在开发一个项目来解析大量文本文件中的唯一单词。我有文件处理,但我正在尝试改进解析过程。每个文件都有一个特定的文本段,以我在实时系统上使用正则表达式捕获的某些短语结尾。
解析器应遍历每一行,并根据3个条件检查每个单词:
dict_file
结果应为2D数组,每行包含每个文件的唯一字列表,在处理完每个文件后使用.writerow(foo)
方法将其写入CSV文件。
我的工作代码如下,但它很慢而且很笨拙,我错过了什么?
我的生产系统仅使用默认模块运行2.5.1(因此NLTK是禁止的),无法升级到2.7+。
def process(line):
line_strip = line.strip()
return line_strip.translate(punct, string.punctuation)
# Directory walking and initialization here
report_set = set()
with open(fullpath, 'r') as report:
for line in report:
# Strip out the CR/LF and punctuation from the input line
line_check = process(line)
if line_check == "FOOTNOTES":
break
for word in line_check.split():
word_check = word.lower()
if ((word_check not in report_set) and (word_check not in dict_file)
and (len(word) > 2)):
report_set.append(word_check)
report_list = list(report_set)
编辑:根据史蒂夫的建议更新了我的代码。
答案 0 :(得分:3)
一个问题是in
的{{1}}测试速度很慢。您应该保留list
来跟踪您看到的字词,因为set
的{{1}}测试速度非常快。
示例:
in
然后当你完成时: report_list = list(report_set)
任何时候你需要强制set
进入report_set = set()
for line in report:
for word in line.split():
if we_want_to_keep_word(word):
report_set.add(word)
,你可以。但是,如果您只需要循环或执行set
测试,则可以将其保留为list
;做in
可能或不重要的另一个问题是,您使用set
方法一次性地从文件中剔除所有行。对于非常大的文件,最好只使用open file-handle对象作为迭代器,如下所示:
for x in report_set:
一个很大的问题是我甚至不知道这段代码是如何工作的:
.readlines()
这将永远循环。第一个语句使用with open("filename", "r") as f:
for line in f:
... # process each line here
覆盖所有输入行,然后我们再次循环,然后对while 1:
lines = report.readlines()
if not lines:
break
的下一个调用.readlines()
已经用尽,因此对.readlines()
的调用返回空列表,它打破了无限循环。但是现在已经丢失了我们刚读过的所有行,其余的代码必须使用空的report
变量。这怎么可以工作?
因此,摆脱整个.readlines()
循环,并将下一个循环更改为lines
。
此外,您实际上不需要保留while 1
变量。您可以随时使用for line in report:
查看count
中有多少字。
另外,对于len(report_set)
,您实际上不需要检查单词是否为set
该集合;您可以随时致电set
,如果它已经在in
,则不会再次添加!
另外,你没有有按照我的方式去做,但我喜欢制作一个能完成所有处理的生成器。剥离线条,平移线条,拆分空白区域,并准备好使用的单词。我也会强制说小写,但我不知道只有大写才能检测到report_set.add(word)
是否很重要。
所以,把以上所有内容放在一起,你得到:
set
答案 1 :(得分:2)
尝试使用字典或集替换report_list。 如果report_list是列表
,则report_list中的word_check不能正常工作