如何搜索大文本文件是否包含使用 python 的句子中的单词?

How to search if large text file contains words from sentence using python?

我有一个包含单词及其 lemma 的文本文件 - 每行在第一列中包含单词形式,在第二列中包含单词引理。

我有一个推文(句子)列表,我需要将其转换为单词引理 - 每个单词都需要转换为其引理(文本文件的第二列)

我尝试为每个单词打开和关闭文本文件,但这花费的时间太长(每个单词大约需要 15 秒才能在文本文件中找到它们的引理)。功能如下

def returnLemma(str):
    str= word_tokenize(str)
    end_str = ""
    for word in str:
        infile = open('MorphDict.txt', 'r')
        for line in infile:
            line.strip()
            prva=line.split()[0] 
            druga=line.split()[1]
            if word==prva:
                end_str = end_str+" "+druga 
                break;
        infile.close()
    return end_str

是否可以更有效地搜索此文本文件 (>100MB)?是否可以使用pandas package来解决这个问题?

当你需要比较两个列表的元素并且一个比另一个小很多时,在内循环中使用最小的。这总是会更有效率。

尽量不要重复做同样的工作。分线的时候,把分线留着,就不用再分线了。

line.strip() 没有改变 line 而是生成一个没有空格的新行。使用 line = line.strip().

您可以搜索到开头,而不是重复打开文件。

我会像这样编写相同的函数:

from collections import defaultdict


word_tokenize = lambda s: s.split()


def returnLemma(s, morph_lines):
    tokens = word_tokenize(s)
    token_positions = defaultdict(list)
    for i, t in enumerate(tokens):
        token_positions[t].append(i)

    drugas = [None] * len(tokens)
    for line in morph_lines:
        line = line.strip()
        parts = line.split(maxsplit=3)
        prva = parts[0]
        try:
            positions = token_positions[prva]
        except KeyError:
            pass
        else:
            druga = parts[1]
            for i in positions:
                drugas[i] = druga

    return ' ' + ' '.join(
        druga if druga is not None else token
        for token, druga in zip(tokens, drugas)
    )


import unittest


class ReturnLemmaTest(unittest.TestCase):

    def test_when_nothing_matches_then_it_returns_a_single_space(self):
        result = returnLemma('hello world', ['line 1', 'line 2'])
        self.assertEqual(' hello world', result)

    def test_when_one_line_matches_then_it_returns_its_second_word(self):
        result = returnLemma('hello world line-b', ['line-a 1', 'line-b 2'])
        self.assertEqual(' hello world 2', result)

    def test_when_many_lines_match_then_it_returns_their_second_words_separated_by_a_space(self):
        result = returnLemma('hello b world b c', ['a 0', 'b 1', 'c 2'])
        self.assertEqual(' hello 1 world 1 2', result)


if __name__ == '__main__':
    unittest.main()

returnLemma 的第二个参数可以是一个打开的文件,但使用列表更容易测试。

这是最终的工作代码 - 对@Javier 的函数进行了微小的更改。谢谢大家的帮助,特别是@Javier 和@MaxU。

from nltk.tokenize import word_tokenize
from collections import defaultdict

def vratiLemu(s, morph_lines):
    tokens = word_tokenize(s)
    token_positions = defaultdict(list)
    for i, t in enumerate(tokens):
        token_positions[t].append(i)

    for line in morph_lines:
        line = line.strip()
        parts = line.split()
        prva = parts[0]
        try:
            positions = token_positions[prva]
        except KeyError:
            pass
        else:
            druga = parts[1]
            for i in positions:
                tokens[i] = druga

    return ' ' + ' '.join(druga for druga in tokens if druga is not None)              

morphDict= open('SveSrpMDANSI.txt', 'r')
out=vratiLemu1("Suštinsko pitanje nije postavljeno: zašto predsednik odbora nije otvorio pretres a morao je",morphDict)
print out

我被问到一个关键问题:为什么委员会主席要开听证会而我必须这样做