如何以O(1)(大O表示法)访问字典中作为键的对象的方法?
如何以O(1)时间复杂度访问字典中作为键的对象的方法?
问题场景
以下代码尝试直接构造等价实例来调用字典键对象的方法,但会报错:
from random import randint class Node(): def GetUse(self): return self.Used def setUse(self): self.Used=True def __init__(self, id): self.id = int(id) self.Used=False def __hash__(self): return hash(self.id) def __eq__(self, other): return self.id == other.id def __str__(self): return f"(id: {self.id}, Used: {self.Used})" def __repr__(self): return f"(id: {self.id}, Used: {self.Used})" def __lt__(self, other): return self.id > other.id N=10 dDict={Node(i):[randint(100,200),randint(100,200)] for i in range(1,N+1)} dDict[Node(1)].setUse() # ERROR
报错原因是dDict[Node(1)]取到的是字典对应的值(一个列表),而非作为键的Node(1)实例,列表没有setUse()方法。
目前已知可通过O(n)的遍历方式实现需求:
for i in dDict: if i==Node(1): i.setUse()
O(1)解决方案
核心思路是提前保存每个Node实例的引用,通过id直接映射到对应实例,无需遍历字典。
修改后的代码示例:
from random import randint class Node(): def GetUse(self): return self.Used def setUse(self): self.Used=True def __init__(self, id): self.id = int(id) self.Used=False def __hash__(self): return hash(self.id) def __eq__(self, other): return self.id == other.id def __str__(self): return f"(id: {self.id}, Used: {self.Used})" def __repr__(self): return f"(id: {self.id}, Used: {self.Used})" def __lt__(self, other): return self.id > other.id N=10 # 先创建所有Node实例,用id映射保存引用 id_to_node = {i: Node(i) for i in range(1, N+1)} # 用映射中的实例构建目标字典 dDict = {node: [randint(100,200), randint(100,200)] for node in id_to_node.values()} # O(1)时间定位实例并调用方法 id_to_node[1].setUse()
原理说明
字典的索引操作dDict[key]仅返回对应的值,不会返回键本身。即使新构造的Node(1)和字典中的键实例满足相等性与哈希一致性,它依然是全新实例,无法直接通过索引获取字典内的原键实例。通过维护id_to_node映射表,我们可以直接通过id快速定位目标实例,实现O(1)的访问效率。
内容的提问来源于stack exchange,提问作者user14272
相关产品推荐
相关产品推荐

