[英]Parsing unique words from a text file
我正在開發一個項目來解析大量文本文件中的獨特單詞。 我有文件處理,但我正在嘗試改進解析過程。 每個文件都有一個特定的文本段,以我在實時系統上使用正則表達式捕獲的某些短語結尾。
解析器應遍歷每一行,並根據3個條件檢查每個單詞:
dict_file
結果應該是2D數組,每行包含每個文件的唯一字列表,在處理.writerow(foo)
每個文件后使用.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)
編輯:根據steveha的建議更新了我的代碼。
一個問題是,一個in
測試的list
是緩慢的。 您應該保留一set
以跟蹤您所看到的單詞,因為對於set
的in
測試非常快。
例:
report_set = set()
for line in report:
for word in line.split():
if we_want_to_keep_word(word):
report_set.add(word)
完成后:report_list = list(report_set)
任何時候你需要強制一個set
到list
,你可以。 但是如果你只是需要循環它或者in
測試中做,你可以把它作為一set
; for x in report_set:
另一個可能或可能不重要的問題是,您使用.readlines()
方法一次性地從文件中.readlines()
所有行。 對於非常大的文件,最好只使用open file-handle對象作為迭代器,如下所示:
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:
中將下一循環更改為for line in report:
此外,您實際上不需要保留count
變量。 您可以隨時使用len(report_set)
來查找set
有多少單詞。
另外,使用一個set
您實際上不需要檢查單詞是否in
集合中; 您可以隨時調用report_set.add(word)
,如果它已經在set
,則不會再次添加!
此外,您不必我的方式去做,但我喜歡做一個發電機,做所有的處理。 剝離線條,平移線條,拆分空白區域,並准備好使用的單詞。 我也會強制說小寫,但我不知道只有大寫才能檢測到FOOTNOTES
是否重要。
所以,把以上所有內容放在一起,你得到:
def words(file_object):
for line in file_object:
line = line.strip().translate(None, string.punctuation)
for word in line.split():
yield word
report_set = set()
with open(fullpath, 'r') as report:
for word in words(report):
if word == "FOOTNOTES":
break
word = word.lower()
if len(word) > 2 and word not in dict_file:
report_set.add(word)
print("Words in report_set: %d" % len(report_set))
嘗試使用字典或集替換report_list。 如果report_list是列表,則word_check不在report_list中工作很慢
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.