我有几十万个关键字放在文件4.txt中,想提取文件3.txt中含有关键字的行,保存到文件5.txt中.
文件3有200万行,我使用下面的代码可以实现我的要求,但是非常慢,一个下午还没运行完,谁有快一点的方法?
使用并行改如何改造呢?我看到这里有个并行的帖子,,与我的不同的事,我要同时读以及查询同一个文件,上述链接可以并行操作多个文件。
with open('3.txt', 'r') as f3, open('4.txt', 'r') as f4, open('result.txt', 'w') as f5:
a = [line.strip() for line in f4.readlines()]
for li in f3.readlines():
new_line = li.strip().split()[1][:-2]
for i in a:
if i in new_line:
f5.writelines(li)
因為沒有實際的文件,沒有辦法給你一個百分之百的保證,不過對於你的 code,我有一些些效率改進上的建議:
(也許你會發現改進後的代碼根本不需要使用並行的解決的方案)
首先一個很大的問題是
readlines()
,這個方法會一口氣讀取 file objects 中的所有行,這對於效率和資源的使用顯然是極差的,幾十萬行幾百萬行的東西要一口氣讀完了,這可是非常恐怖的.詳細的分析和討論請參考Never call readlines() on a file
(文章中的這段話幾乎可當作是警語了)
結論是: 建議所有使用
readlines
的地方全部改掉.範例:
一律改成:
直覺上效率會好很多.
其次,你使用了 list 來查找關鍵字,這也是相當沒效率的:
為了確認
new_line
中是否有關鍵字i
,這邊走訪了一整個關鍵字 list:a
,對於一般的情況可能還好,但是數十萬的關鍵字比對,對每一行都走訪一次a
會造成大量的時間浪費,假設a
裡面有 x 個關鍵字,f3
中有 y 行,每行有 z 個字,這邊要花的時間就是x*y*z
(根據你文件的行數,這個數量級極為驚人).如果簡單地利用一些使用 hash 來查找的容器肯定會好一些,比如說
dictionary
或是set
.最後是關於你的查找部分:
這邊我不是很懂,
new_line
看起來是一個子字串,然後現在要用這個字串去比對關鍵字?不過先撇開這個不談,關於含有關鍵字的
new_line
在印出後,似乎不該繼續循環a
,除非你的意思是new_line
中有幾個關鍵字我就要印line
幾次. 否則加上一個break
也是可以加快速度.建議你的code改為:
如果我有弄錯你的意思,歡迎跟我說,我們再來討論一下,直覺上應該不必使用到並行就可以解決你的問題