我正在编写一个Graph类来处理游戏中的路径。图有一个字段,即映射,它是将节点映射到边的字典。在我的一个函数中,我有以下代码:
for key in self.mapping:
connected_edges = self.mapping[key]
在我的程序中的某一点上,我调用此代码并收到以下错误:
KeyError: <node.Node instance at 0x00000000026F3088>
这怎么可能?我只是循环遍历字典中的键,那么键怎么可能不在其中呢?为了理智检查,我拿了字典的长度,看到它是5,即:不是0.任何想法?谢谢!
我为Node和Edge实现了我自己的 eq 和哈希方法。以下是课程的这些部分:
class Node:
"""
A node connects to other nodes via Edges to form a graph
Each node has a unique identifier (ID) so they can be mathematically distinct. Optionally, a node also has an x and
y coordinate.
"""
n_nodes = 0
def __init__(self, x=0, y=0):
"""
Create a node with its own unique identifier.
:param x: x coordinate
:param y: y coordinate
:return: an initialized Node object
"""
Node.n_nodes += 1
self.ID = Node.n_nodes
self.x = x # x position
self.y = y # y position
def __eq__(self, other):
return (self.ID, self.x, self.y) == (other.ID, other.x, other.y)
def __hash__(self):
return hash((self.ID, self.x, self.y))
class Edge:
"""
An edge is a connection between two nodes.
Edges have a unique identifier and a list of two nodes. Optionally, an edge can have a numerical weight. Edges can
also be directed, in which case it is only possible to traverse the edge in one direction, not both.
"""
n_edges = 0
def __init__(self, node1, node2, weight=1, directed=False):
"""
Create an edge with its own unique identifier
:param node1: node at first end of the edge
:param node2: node at second end of the edge
:param weight: numerical weight of the connection between node1 and node2
:param directed: if True, the edge is oriented from node1 to node 2
:return: an initialized Edge object
"""
Edge.n_edges += 1
self.ID = Edge.n_edges
self.weight = weight
self.nodes = frozenset([node1, node2])
self.directed = directed
def __eq__(self, other):
return (self.ID, self.weight, self.nodes, self.directed) == (other.ID, other.weight, other.nodes, other.directed)
def __hash__(self):
return hash((self.ID, self.weight, self.nodes, self.directed))
答案 0 :(得分:2)
如果您的对象实现__eq__
和__hash__
,则必须确保在创建对象后哈希值不会更改。如果在创建对象后改变对象,则可以使它们进入不一致状态,即在字典中为它们存储的哈希值与其当前哈希值不一致。这是一个例子:
class Foo(object):
def __init__(self, x):
self.x = x
def __eq__(self, other):
return self.x == other.x
def __hash__(self):
return self.x
a, b, c = Foo(1), Foo(2), Foo(3)
x = {a: 1, b: 2, c: 3}
for key in x:
print(x[key])
a.x = 100
for key in x:
print(x[key])
结果是KeyError类似于您收到的KeyError。据推测,你正在改变你的Node对象。
不能对可变对象进行哈希处理(或者至少,它们的哈希值不能取决于它们的任何可变状态)。