我有一个包含大约400个单词的列表。另一个列表列表,其中每个列表包含大约150,000个单词。这份清单有20个这样的清单。
现在我想看看这些150,000个单词列表中出现的400个单词中有多少个。我也想从这400个单词中知道一个单词,在150k单词列表中出现多少次,这些单词中出现的最多,多少次等等。
我能想到的唯一解决方案是多项式时间解决方案。这是一个非常糟糕的解决方案,并且会很慢:
for one_list in list_of_150kwords:
for key in 400_words:
for word in one_list:
if key == word:
# count this word
# do other stuff
这是一个非常丑陋和糟糕的解决方案,但我无法想到更好。我通过将这些列表转换为NumPy数组来尝试使用NumPy:
list_of_150kwords = numpy.array(list_of_150kwords)
...
但我仍觉得它很慢。还有其他方法吗?还是任何图书馆?
答案 0 :(得分:13)
这听起来像是使用set
的好机会:
set_of_150kwords = set(list_of_150kwords)
one_set = set(one_list)
len(one_set & set_of_150kwords) # set intersection is &
=> number of elements common to both sets
根据集理论,两个集合的交集给出了出现在两个集合中的元素,然后它是一个简单的问题。对于第二部分(这些单词中出现的最多,多少次等)使用list_of_150kwords
创建Counter
,这将告诉您每个单词在列表中出现的次数。并且交集会告诉您哪些是常用词,解决了您的两个要求。
答案 1 :(得分:1)
from collections import Counter
search_data = [
["list", "of", "150k", "words"],
["another", "list", "of", "150k", "words"],
["yet", "another", "list", "of", "150k", "words"]
# ... 17 more of these
]
search_words = ["four", "hundred", "words", "to", "search", "for"]
def word_finder(words_to_find):
lookfor = set(word.lower() for word in words_to_find)
def get_word_count(text):
return Counter(word for word in (wd.lower() for wd in text) if word in lookfor)
return get_word_count
def get_words_in_common(counters):
# Maybe use c.viewkeys() instead of set(c)? Which is faster?
return reduce(operator.and_, (set(c) for c in counters))
def main():
wordcount = word_finder(search_words)
counters = [wordcount(wordlst) for wordlst in search_data]
common_to_all = get_words_in_common(counters)
print(common_to_all)
if __name__=="__main__":
main()
答案 2 :(得分:0)
这是Trie有用的地方的规范示例。您需要为每个150K列表创建一个Trie。然后,您可以在O(W)时间内检查列表中是否存在给定的单词。其中W是单词的最大长度。
然后你可以遍历400个单词的列表并检查每个作品是否在150K单词列表中。
鉴于L即150K列表的数量远小于150K且W远小于150K,所以没有设置连接将与Trie比较一样快。
最终的运行复杂性:
N = 400 //Size of small list
W = 10 // Max word Length
M = 150K // Max size of the 150K lists
P = 4 // Number of 150K lists
P * M // To construct Trie
N * P * W // To find each word in the 150k lists
MP + NPW // Total complexit
答案 3 :(得分:0)