我正在尝试创建一个可以搜索文档中特定键的脚本。有时文件可能非常大,我想要的东西可以非常快速有效,并且可以使用尽可能少的内存。
这是我的代码
Keys=('key1','key2','key3','key4','key5',...,'keyN')
LKeys=list(Keys)
with open('test.txt', 'r') as inF:
for (N,line) in enumerate(inF):
if any(x in line for x in LKeys):
for k in LKeys:
if k in line:
print N,k,line
print inF.next().strip()
# Depending of the key sometimes I need to print next N lines
#Or do something else with the line for example save the next element after the key in a dictionary or database
LKeyword.remove(k)
inF.close()
test.txt看起来像这样。
sdjskjd key1 jdjdjjd : 4
sdjskjd key2 jdjdjjd: 3 hdhdhd:NaN
sdjskjd key4 jdjdjjd:
dfdgdfdfdffddfdf2t3h
dfdfdfdfdf5dfd3fhth21
dfdfdfdgghhgdhhghjh
.
.
.
sdjskjd keyN jdjdjjd : 1213.5678 Inz:Joe
例如:
Author Antoine de Saint-Exupéry
Original title Le Petit Prince
Translator (English editions)
Katherine Woods
T.V.F. Cuffe
Irene Testot-Ferry
Alan Wakeman
Richard Howard[1]
David Wilkinson
Illustrator Antoine de Saint-Exupéry
Cover artist Antoine de Saint-Exupéry
Country France
Language French
Publisher Reynal & Hitchcock (U.S.)
Gallimard (France)[2]
Publication date
September 1943 (U.S.: English & French)
(France, French, 1945)[2][Note 1]
Preceded by Pilote de guerre (1942)
Followed by Lettre à un otage (1944)
Author Jostein Gaarder
Original title Sofies verden
Country Norway
Language Norwegian
Genre Philosophical novel
Publisher Berkley Books, Farrar, Straus and Giroux (original hardcover), MacMillan (audio)
Publication date
1991
Published in English
1994
Media type Print (hardcover & paperback) and audiobook (English, unabridged CD & download)
Pages 518 pp
ISBN 978-1-85799-291-5
ISBN 978-1-4272-0087-7
ISBN 978-1-4272-0086-0
OCLC 246845141
LC Class MLCM 92/06829 (P)
Auteur Gabriel García Márquez
Pays Drapeau de la Colombie Colombie
Genre Roman
Réalisme magique
Version originale
Langue Espagnol
Titre Cien años de soledad
Éditeur Editorial Sudamericana
Lieu de parution Buenos Aires
Date de parution 1967
Version française
Traducteur Claude et Carmen Durand
Éditeur Éditions du Seuil
Lieu de parution Paris
Date de parution 1968
Couverture Élizabeth Butterworth
Nombre de pages 437
ISBN 202023811X
我读到,顺序访问行的简单迭代有时候是搜索和匹配大型文档的内存要求较少的方法,有时比正则表达式更快。
关于我的密钥的一些评论他们通常按照我的文档中的顺序出现,如果找到密钥,它将不再出现,我将其从列表中删除,但是,有些情况下并非所有密钥都出现在文档中但是如果找到了key2,那么key4很可能是key3不在文档中。此外,键是不可变的,并在文档中显示为准确的单词。
是否有更好,更有效,更干净的方法来构建代码?
答案 0 :(得分:1)
所以下面的代码,而不是使用一个元组或列表,它使用一个集合。这意味着如果有数千个键,查找仍将处于恒定时间。在列表中,如果执行key in ['key', ..., 'keyN']
对于每一行,我们将空格分开,以便我们可以在键中进行查找。然后,如果单词存在,我们可以打印它。如果您需要从键中删除键,则必须缩小拆分词并再次检查。
但是,由于检查集合中的密钥是在固定时间内发生的,因此出于效率原因,您不必真正删除密钥。
考虑到一行中只能有这么多单词,这个效率会更高。但可能有N键。
keys = {'key1','key2','key3','key4','key5',...,'keyN'}
with open('test.txt', 'r') as f:
for no, line in enumerate(f):
words = line.split()
for word in words:
if word in keys:
print(no, line)
# find out which word actually matched by repeatedly
# shrinking a copy of the list words.
# then you could remove the key from keys
此外,您无需关闭该文件。上下文管理器(即with)负责在读取文件后关闭文件。
答案 1 :(得分:0)
我对你的代码做了一些调整。我不知道这是不是你想要的,但无论如何这都有效。
Keys = ('Cover', "Cuffe")
with open('test.txt', 'r', encoding="utf-8") as inF:
for (N, line) in enumerate(inF):
if any(x in line.split() for x in Keys):
for k in Keys:
if k in line.split():
print("(line)", N,
"(key)", k,
"(result)", line)
输出(使用txt文件示例中的数据)是:
(line)4(key)Cuffe(result)T.V.F。卡夫
(线)10(键)封面(结果)封面艺术家Antoine de 圣埃克苏佩里
Keys = ('Cover', "Cuffe")
with open('test.txt', 'r', encoding="utf-8") as inF:
for (N, line) in enumerate(inF):
if any(x in line.split() for x in Keys):
for k in Keys:
if k in line.split():
print "(line)", N,
"(key)", k,
"(result)", line