如何快速从列表中获得独特的单词?

时间:2018-12-07 08:37:39

标签: python lambda nlp nltk execution

我有一个包含300万个句子的文件(大约)。每个句子大约有60个字。我想结合所有单词,并从中找到独特的单词。

我尝试了以下代码:

 final_list = list()
 for sentence in sentence_list:
     words_list = nltk.word_tokenize(sentence)
     words = [word for word in words_list if word not in stopwords.words('english') ]
     final_list = final_list + set(words)

此代码给出了独特的词,但是处理时间太长。每小时约5万句。处理可能需要3天。

我也尝试了lambda函数:

    final_list = list(map(lambda x: list(set([word for word in sentence])) ,sentence_list))

但是,执行没有明显改善。请提出一个有效的执行时间更好的解决方案。欢迎提出并行处理建议。

1 个答案:

答案 0 :(得分:3)

您需要懒惰地做所有事情,并使用尽可能少的中间列表,并尽可能减少重复次数和处理时间。 文件中的所有唯一词:

import itertools
def unique_words_from_file(fpath):
    with open(fpath, "r") as f:
        return set(itertools.chain.from_iterable(map(str.split, f)))

让我们在这里解释一下想法。

文件对象是可迭代的对象,这意味着您可以遍历文件的每一行!

然后,我们希望每一行中的单词都被分开。在这种情况下,我们使用map中的Python3(或itertools.imap中的Python2)来创建一个对象,并在文件行上进行该计算。 mapimap也是懒惰的,这意味着默认情况下不会分配任何中间列表,这真是太棒了,因为我们不会在不需要的东西上花费任何资源!

由于str.split返回一个列表,因此我们的map结果将是一连串的字符串列表,但是我们需要遍历每个字符串。为此,无需构建另一个list,我们可以使用itertools.chain来展平结果!

最后,我们调用set,它将遍历这些单词,并且每个单词仅保留一个。瞧!

让我们有所进步!,我们可以让str.split变得懒惰吗?, 是!检查此SO answer

import itertools
import re

def split_iter(string):
    return (x.group(0) for x in re.finditer(r"[A-Za-z']+", string))

def unique_words_from_file(fpath):
    with open(fpath, "r") as f:
        return set(itertools.chain.from_iterable(map(split_iter, f)))
相关问题