Python字典迭代获取目标值关联键的代码输出异常排查
问题排查与解决方案
问题背景
给定以下数据:
source_list = ['a', 'b'] target_list = ['x', 'y', 'z'] my_dict = { 'a': ['e'], 'b': ['f', 'd'], 'e': ['g'], 'f': ['t', 'h'], 'd': ['x'], 'g': ['x'], 't': ['y'], 'h': ['z'] }
需求是从source_list开始,迭代获取my_dict中的键,直到得到target_list中的值,将迭代次数作为输出字典的键,预期输出:
{0: {'a': ['e'], 'b': ['f', 'd']}, 1: {'e': ['g'], 'f': ['t', 'h'], 'd': ['x']}, 2: {'g': ['x'], 't': ['y'], 'h': ['z']}}
编写的代码如下:
from collections import deque source_list = ['a', 'b'] target_list = ['x', 'y', 'z'] my_dict = {'a': ['e'], 'b': ['f', 'd'], 'e': ['g'], 'f': ['t', 'h'], 'd': ['x'], 'g': ['x'], 't': ['y'], 'h': ['z']} result_dict = {} queue = deque([(0, my_dict)]) while queue: iteration, current_dict = queue.popleft() result_dict[iteration] = {key: current_dict[key] for key in source_list if key in current_dict} next_dict = {item: my_dict.get(item, []) for key in result_dict[iteration] for item in current_dict[key]} if any(target_value in next_dict for target_value in target_list): queue.append((iteration + 1, next_dict)) print(result_dict)
实际输出仅为:
{0: {'a': ['e'], 'b': ['f', 'd']}}
问题排查
原代码存在3个核心问题:
- 队列初始值错误:队列中存入的是整个
my_dict,但每一轮需要处理的是当前节点列表,而非完整字典,导致后续逻辑混乱。 - 终止条件逻辑错误:
target_list中的元素是最终值(如x、y),而next_dict的键是中间节点,判断target_value in next_dict永远为假,因此不会添加下一轮迭代任务到队列。 - 迭代节点未更新:每一轮生成结果时始终使用初始的
source_list,而非前一轮迭代得到的子节点作为当前轮的处理对象。
修正后的代码
from collections import deque source_list = ['a', 'b'] target_list = ['x', 'y', 'z'] my_dict = {'a': ['e'], 'b': ['f', 'd'], 'e': ['g'], 'f': ['t', 'h'], 'd': ['x'], 'g': ['x'], 't': ['y'], 'h': ['z']} result_dict = {} # 队列存储(迭代次数, 当前要处理的节点列表) queue = deque([(0, source_list)]) while queue: iteration, current_nodes = queue.popleft() # 收集当前节点对应的字典条目 current_entry = {node: my_dict[node] for node in current_nodes if node in my_dict} result_dict[iteration] = current_entry # 提取下一轮要处理的节点:当前节点的所有子节点 next_nodes = [] for node in current_entry: next_nodes.extend(my_dict[node]) # 检查是否还有需要迭代的节点:下一轮节点不全是target_list中的值 has_non_target = any(node not in target_list for node in next_nodes) if next_nodes and has_non_target: # 去重避免重复处理相同节点 unique_next_nodes = list(set(next_nodes)) queue.append((iteration + 1, unique_next_nodes)) print(result_dict)
代码逻辑说明
- 队列存储迭代次数和当前要处理的节点列表,而非完整字典,明确每一轮的处理对象。
- 每一轮根据当前节点列表生成对应的字典条目,存入结果。
- 提取当前节点的所有子节点作为下一轮的处理对象,同时判断是否需要继续迭代:只要存在非
target_list的节点,就继续执行下一轮。 - 对下一轮节点去重,避免重复处理相同节点导致冗余。
运行后输出与预期完全一致:
{0: {'a': ['e'], 'b': ['f', 'd']}, 1: {'e': ['g'], 'f': ['t', 'h'], 'd': ['x']}, 2: {'g': ['x'], 't': ['y'], 'h': ['z']}}
内容的提问来源于stack exchange,提问作者Roxane Felton
相关产品推荐
相关产品推荐

