Maison > Questions et réponses > le corps du texte
我有几十万个关键字放在文件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)
阿神2017-04-17 17:47:22
Comme il n'y a pas de fichiers réels, je ne peux pas vous donner une garantie à 100 %, mais pour votre code, j'ai quelques suggestions pour améliorer l'efficacité :
(Peut-être constaterez-vous que le code amélioré ne nécessite pas du tout de solution parallèle)
Tout d'abord, un gros problème est readlines()
. Cette méthode lira toutes les lignes des objets fichier en une seule fois, ce qui est évidemment extrêmement mauvais en termes d'efficacité et d'utilisation des ressources. lignes. Je dois tout lire d'une seule traite, ce qui fait très peur.
Pour une analyse et une discussion détaillées, veuillez vous référer à Ne jamais appeler readlines() sur un fichier
(Ce paragraphe de l'article peut presque être considéré comme un avertissement)
Il y a des centaines de questions sur des sites comme StackOverflow à propos de la méthode readlines, et dans tous les cas, la réponse est la même.
"Mon code prend une éternité avant même de démarrer, mais il est assez rapide une fois que ça démarre."
C'est parce que vous appelez readlines.
"Mon code semble être pire que linéaire en termes de taille de l'entrée, même s'il ne s'agit que d'une simple boucle. "
C'est parce que vous appelez readlines.
"Mon code ne peut pas gérer des fichiers géants car il manque de mémoire."
C'est parce que vous appelez lignes de lecture.
La conclusion est la suivante : Il est recommandé que tous les endroits où readlines
sont utilisés soient remplacés par .
Exemple :
with open('XXX', 'r') as f:
for line in f.readlines():
# do something...
doit être remplacé par :
with open('XXX', 'r') as f:
for line in f:
# do something...
Intuitivement, l’efficacité sera bien meilleure.
Deuxièmement, vous avez utilisé la liste pour trouver des mots-clés, ce qui est également assez inefficace :
for i in a:
if i in new_line:
Afin de confirmer s'il y a un mot-clé new_line
dans i
, nous avons visité toute la liste de mots-clés : a
, ce qui peut convenir pour des situations générales, mais pour des centaines de milliers de comparaisons de mots-clés, c'est Visiter chaque ligne de a
entraînera beaucoup de perte de temps. Supposons qu'il y ait x mots-clés dans a
, y lignes dans f3
et z mots dans chaque ligne. Le temps passé ici est de x*y*z
(en fonction. sur le nombre de lignes de votre fichier, cet ordre de grandeur est extrêmement ahurissant).
Il serait certainement préférable d'utiliser simplement un conteneur qui utilise du hachage pour rechercher, tel que dictionary
ou set
.
La dernière partie concerne votre recherche :
for li in f3.readlines():
new_line = li.strip().split()[1][:-2]
for i in a:
if i in new_line:
f5.writelines(li)
Je ne comprends pas très bien cela, new_line
semble être une sous-chaîne, et maintenant vous souhaitez utiliser cette chaîne pour comparer des mots-clés ?
Mais en mettant cela de côté, concernant new_line
contenant des mots-clés, il semble qu'après l'impression, il ne devrait pas continuer à boucler a
, à moins que vous vouliez dire qu'il y a plusieurs mots-clés dans new_line
que je souhaite imprimer line
Plusieurs fois. Sinon, ajouter un break
peut également accélérer le processus.
Il est recommandé de changer votre code en :
with open('3.txt') as f3, open('4.txt') as f4, open('result.txt', 'w') as f5:
keywords = set(line.strip() for line in f4)
for line in f3:
new_line = line.strip().split()[1][:-2]
for word in new_line:
if word in keywords:
print(line, file=f5)
break
Si je me suis trompé, dites-le-moi et discutons-en à nouveau Intuitivement, votre problème peut être résolu sans utiliser le parallélisme
黄舟2017-04-17 17:47:22
D'après la réponse de @dokelung, avec de légères modifications, il peut essentiellement répondre à mes exigences. Cette réponse est quelque peu différente de l'utilisation de grep -f 4.txt 3.txt > Je compare les différences entre les deux fichiers de résultats.
with open('3.txt') as f3, open('4.txt') as f4, open('result.txt', 'w') as f5:
keywords = set(line.strip() for line in f4)
for line in f3:
new_line = line.strip().split()[1][:-2]
if new_line in keywords:
print(line.strip(), file=f5)