Python高效处理37万词JSON文件,实现Scrabble最优得分单词查找
高效实现方案
1. 预处理单词库(仅需执行一次)
- 加载JSON单词文件后,完成两项预计算:
- 计算每个单词的总得分:用字母分值字典累加每个字母的得分,替换原JSON中无意义的
1值。 - 统计每个单词的字母频次:用
collections.Counter将单词转换为字母计数结构(比如"aahed"转成{'a':2, 'h':1, 'e':1, 'd':1})。
- 计算每个单词的总得分:用字母分值字典累加每个字母的得分,替换原JSON中无意义的
- 将预处理后的单词数据按得分从高到低排序,得分相同的按单词长度从长到短排列。这样遍历过程中,找到第一个符合条件的单词就是最高分单词,无需遍历全部37万条数据。
2. 处理输入字母
- 用
collections.Counter统计输入变量word的字母频次,记为input_counter,后续用于快速校验单词是否可组成。
3. 快速筛选符合条件的单词
- 遍历预处理好的排序后列表:
- 对每个单词的字母频次,校验所有字母的计数是否均不超过
input_counter中的对应计数(比如单词需要2个a,输入里至少要有2个a)。 - 找到第一个满足条件的单词即可返回,因为列表是降序排列,后续单词得分不会更高。若需收集所有最高分单词,可继续遍历至得分低于当前最高分。
- 对每个单词的字母频次,校验所有字母的计数是否均不超过
核心优化点
- 避免重复计算:预处理阶段一次性完成得分和频次统计,彻底解决普通循环中重复计算导致的性能问题和崩溃风险。
- 放弃多线程:Python GIL会导致CPU密集型任务的多线程调度开销大于收益,单线程有序遍历效率更高。
- 提前截断遍历:利用排序后的结构,一旦遇到得分低于当前已找到的最高分,直接终止遍历,大幅减少计算量。
代码示例
import json from collections import Counter import pickle # Scrabble字母分值字典 LETTER_SCORES = { "a": 1, "b": 2, "c": 2, "d": 3, "e": 1, "f": 4, "g": 2, "h": 4, "i": 1, "j": 8, "k": 5, "l": 1, "m": 3, "n": 1, "o": 1, "p": 3, "q": 10, "r": 1, "s": 1, "t": 1, "u": 1, "v": 4, "w": 4, "x": 8, "y": 4, "z": 10 } def preprocess_word_list(json_path): # 加载原始单词库 with open(json_path, 'r') as f: raw_words = json.load(f) processed = [] for word in raw_words.keys(): # 计算单词总得分 total_score = sum(LETTER_SCORES[char] for char in word) # 统计字母频次 char_count = Counter(word) # 用负分实现升序排序(等价于正分降序),同时按长度降序 processed.append( (-total_score, -len(word), char_count, word) ) processed.sort() # 转换为正分结构返回 return [ (-score, -length, cnt, word) for score, length, cnt, word in processed ] def find_top_score_word(input_word, processed_words): input_cnt = Counter(input_word.lower()) max_score = 0 best_word = None for score, _, word_cnt, word in processed_words: if score <= max_score: # 后续单词得分不会更高,直接终止遍历 break # 校验单词是否可由输入字母组成 if all(word_cnt[char] <= input_cnt.get(char, 0) for char in word_cnt): max_score = score best_word = word # 若只需第一个最高分单词,可直接返回 # return best_word, max_score return best_word, max_score # 用法示例 if __name__ == "__main__": # 第一次运行预处理并缓存结果,后续直接加载缓存 try: with open("scrabble_processed.pkl", 'rb') as f: processed_words = pickle.load(f) except FileNotFoundError: processed_words = preprocess_word_list("scrabble_words.json") with open("scrabble_processed.pkl", 'wb') as f: pickle.dump(processed_words, f) input_word = "aahedxyz" best_word, score = find_top_score_word(input_word, processed_words) print(f"最高分单词:{best_word},得分:{score}")
内容的提问来源于stack exchange,提问作者TheBlooner
相关产品推荐
相关产品推荐

