如何修改字典值(集合存储)中的单个Node对象属性?
问题分析与解决方案
你的问题核心是:修改edge.visited = True后,后续迭代中该Node的visited属性仍为False,这是因为你操作的Node对象与字典/集合中存储的不是同一个实例——即使它们的id、region属性完全相同,默认情况下Python会把它们当成不同的对象。
原因详解
Python中字典的键、集合的元素依赖对象的__hash__和__eq__方法。默认情况下,这两个方法基于对象的内存地址实现:两个属性完全一致的Node实例,只要是分开创建的,就会被视为不同的对象。这意味着你从self.map[current_node]中取出的edge,可能只是和目标Node属性相同的另一个实例,修改它的visited自然不会影响字典/集合中存储的那个真实节点。
解决步骤
1. 给Node类实现__hash__和__eq__方法
让Python根据Node的唯一标识(即id)来判断对象是否相等,确保相同id的Node被视为同一个对象:
class Node: def __init__(self, row, column, region): self.id = f'{str(row)}-{str(column)}' self.region = region self.visited = False def __hash__(self): # 基于唯一id计算哈希值 return hash(self.id) def __eq__(self, other): # 仅当id相同时,两个Node对象才相等 if isinstance(other, Node): return self.id == other.id return False
2. 避免重复创建Node实例
在创建Node对象时,通过缓存机制确保相同row和column的节点只被创建一次:
# 全局缓存字典,用node_id作为键 _node_cache = {} def get_node(row, column, region): node_id = f'{row}-{column}' if node_id not in _node_cache: _node_cache[node_id] = Node(row, column, region) return _node_cache[node_id]
之后所有需要获取Node的地方都调用get_node函数,确保拿到的是同一个实例。
验证你的遍历逻辑
完成上述修改后,你的遍历代码逻辑是正确的:
while nodes_queue: current_node = nodes_queue.pop() for edge in self.map[current_node]: if edge.region == root.region and not edge.visited: edge.visited = True # 现在修改的是真实节点的属性 nodes_queue.append(edge)
此时修改edge.visited会直接作用于字典/集合中存储的Node实例,后续迭代时visited会保持为True。
内容的提问来源于stack exchange,提问作者tojzke
相关产品推荐
相关产品推荐

