我有几十万个关键字放在文件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)
Oleh kerana tiada fail sebenar, saya tidak dapat memberi anda jaminan 100%, tetapi untuk kod anda, saya mempunyai beberapa cadangan untuk peningkatan kecekapan:
(Mungkin anda akan mendapati bahawa kod yang dipertingkatkan tidak memerlukan penyelesaian selari sama sekali)
Pertama sekali, masalah besar ialah
readlines()
Kaedah ini akan membaca semua baris dalam objek fail sekali gus Ini jelas sangat lemah untuk kecekapan dan penggunaan sumber baris. Saya perlu membaca semuanya dalam satu sesi, yang sangat menakutkan.Untuk analisis dan perbincangan terperinci, sila rujuk Jangan sekali-kali memanggil readlines() pada fail
(Perenggan dalam artikel ini hampir boleh dianggap sebagai amaran)
Kesimpulannya ialah: Adalah disyorkan bahawa semua tempat di mana
readlines
digunakan hendaklah ditukar kepada .Contoh:
mesti ditukar kepada:
Secara intuitif, kecekapan akan menjadi lebih baik.
Kedua, anda menggunakan senarai untuk mencari kata kunci, yang juga agak tidak cekap:
Untuk mengesahkan sama ada terdapat kata kunci
new_line
dalami
, kami melawati keseluruhan senarai kata kunci:a
, yang mungkin baik untuk situasi umum, tetapi untuk ratusan ribu perbandingan kata kunci, ia adalah Melawat setiap barisa
akan menyebabkan banyak pembaziran masa Katakan terdapat x kata kunci dalama
, y baris dalamf3
dan z perkataan dalam setiap baris Masa yang dihabiskan di sini ialahx*y*z
(Bergantung pada bilangan baris dalam fail anda, susunan magnitud ini sangat mengejutkan).Sudah tentu adalah lebih baik untuk hanya menggunakan beberapa bekas yang menggunakan cincang untuk mencari, seperti
dictionary
atauset
.Bahagian terakhir ialah tentang carian anda:
Saya tidak begitu memahami perkara ini,
new_line
nampaknya subrentetan, dan kini anda mahu menggunakan rentetan ini untuk membandingkan kata kunci?Tetapi mengetepikan perkara ini, mengenai
new_line
yang mengandungi kata kunci, nampaknya selepas mencetak, ia tidak sepatutnya terus bergelunga
, melainkan anda maksudkan terdapat beberapa kata kunci dalamnew_line
yang ingin saya cetakline
Beberapa kali. Jika tidak, menambahbreak
juga boleh mempercepatkan proses.Adalah disyorkan bahawa kod anda ditukar kepada:
Jika saya salah faham, sila beritahu saya dan mari kita bincangkan semula secara intuitif, masalah anda boleh diselesaikan tanpa menggunakan selari
automaton ac
Berdasarkan jawapan @dokelung, dengan sedikit pengubahsuaian, ia pada asasnya boleh memenuhi keperluan saya. Jawapan ini agak berbeza daripada menggunakan grep -f 4.txt 3.txt > 5.txt;