Python合并字典不覆盖值及树节点多IDF值存储问题
嘿,这个问题我之前也碰到过——普通的字典合并会直接覆盖重复key的值,完全没法满足你这种要保留树中所有节点IDF的需求。别担心,咱们分两步来解决:先搞定多字典不覆盖合并的基础逻辑,再把它适配到树结构的遍历场景里。
一、基础:多字典不覆盖合并的核心思路
核心就是把每个单词对应的IDF值从单个值改成一个容器(比如列表),这样重复key的新值就不会覆盖旧值,而是被追加到容器里。
比如你有几个独立的IDF字典,用下面的方法就能合并且不丢失任何值:
from collections import defaultdict def merge_idf_dicts(dict_list): # 用defaultdict自动给新key初始化空列表 merged = defaultdict(list) for idf_dict in dict_list: for word, idf_value in idf_dict.items(): merged[word].append(idf_value) # 可选:转成普通字典(如果不需要defaultdict的特性) return dict(merged) # 测试示例 dict_a = {"cat": 0.75, "dog": 0.6} dict_b = {"cat": 0.8, "bird": 0.5} dict_c = {"dog": 0.65, "fish": 0.4} result = merge_idf_dicts([dict_a, dict_b, dict_c]) print(result) # 输出:{'cat': [0.75, 0.8], 'dog': [0.6, 0.65], 'bird': [0.5], 'fish': [0.4]}
如果不用defaultdict,用普通字典手动判断也可以,逻辑是一样的。
二、适配树结构:遍历所有节点汇总IDF
树结构的关键是先遍历所有节点(不管是深度优先还是广度优先),再把每个节点的IDF字典按上面的方法合并。
假设你的树节点是这样定义的(可以根据你实际的节点结构调整):
class TreeNode: def __init__(self, node_name, idf_dict): self.node_name = node_name # 用来标识节点,方便溯源 self.idf_dict = idf_dict # 当前节点的IDF字典 self.children = [] # 子节点列表
然后写一个遍历树并合并的函数:
def collect_all_node_idfs(root_node): merged_idf = defaultdict(list) def traverse(node): # 合并当前节点的IDF值,同时记录节点名称(可选) for word, idf_value in node.idf_dict.items(): # 如果需要知道这个IDF来自哪个节点,就存元组(节点名, IDF值) merged_idf[word].append( (node.node_name, idf_value) ) # 递归遍历子节点 for child in node.children: traverse(child) traverse(root_node) return dict(merged_idf) # 构建测试树 root = TreeNode("节点A", {"cat": 0.75, "dog": 0.6}) child_b = TreeNode("节点B", {"cat": 0.8, "bird": 0.5}) child_c = TreeNode("节点C", {"dog": 0.65, "cat": 0.7}) root.children = [child_b, child_c] # 汇总所有节点的IDF final_result = collect_all_node_idfs(root) print(final_result) # 输出: # {'cat': [('节点A', 0.75), ('节点B', 0.8), ('节点C', 0.7)], # 'dog': [('节点A', 0.6), ('节点C', 0.65)], # 'bird': [('节点B', 0.5)]}
这样每个单词对应的所有节点的IDF值都被完整保留了,还能知道每个值来自哪个节点,完全解决了覆盖丢失的问题。
三、进阶:按需调整存储结构
如果你不需要溯源节点,只需要所有IDF值的集合,把(node.node_name, idf_value)改成idf_value就行;如果需要去重,可以把列表换成集合(但要注意IDF是浮点数,去重要考虑精度问题);甚至可以统计每个IDF值出现的次数,用defaultdict(int)来计数。
内容的提问来源于stack exchange,提问作者adi5257
相关产品推荐
相关产品推荐

