如何快速从列表中获取唯一的单词?
How to get unique words from a list quickly?
我有一个包含 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))
但是,执行力并没有明显的提升。请提出有效执行时间的更好解决方案。欢迎并行处理建议。
您需要懒惰地完成所有操作,并使用尽可能少的中间列表(减少分配和处理时间)。
文件中的所有唯一单词:
import itertools
def unique_words_from_file(fpath):
with open(fpath, "r") as f:
return set(itertools.chain.from_iterable(map(str.split, f)))
让我们在这里解释一下这些想法。
文件对象是可迭代对象,这意味着您可以迭代文件的行!
然后我们想要每行的单词,这就是拆分它们。在这种情况下,我们使用 Python3
中的 map
(或 Python2
中的 itertools.imap
)来创建一个对象,该对象在我们的文件行上进行计算。 map
和 imap
也是惰性的,这意味着默认情况下不会分配任何中间列表,这很棒,因为我们不会在不需要的东西上花费任何资源!
由于 str.split
returns 一个列表,我们的 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)))
我有一个包含 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))
但是,执行力并没有明显的提升。请提出有效执行时间的更好解决方案。欢迎并行处理建议。
您需要懒惰地完成所有操作,并使用尽可能少的中间列表(减少分配和处理时间)。 文件中的所有唯一单词:
import itertools
def unique_words_from_file(fpath):
with open(fpath, "r") as f:
return set(itertools.chain.from_iterable(map(str.split, f)))
让我们在这里解释一下这些想法。
文件对象是可迭代对象,这意味着您可以迭代文件的行!
然后我们想要每行的单词,这就是拆分它们。在这种情况下,我们使用 Python3
中的 map
(或 Python2
中的 itertools.imap
)来创建一个对象,该对象在我们的文件行上进行计算。 map
和 imap
也是惰性的,这意味着默认情况下不会分配任何中间列表,这很棒,因为我们不会在不需要的东西上花费任何资源!
由于 str.split
returns 一个列表,我们的 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)))