首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >作为字典键的自定义类型的对象

作为字典键的自定义类型的对象
EN

Stack Overflow用户
提问于 2011-02-05 02:51:40
回答 3查看 112.5K关注 0票数 216

我必须做什么才能使用我的自定义类型的对象作为Python字典中的键(我不想让"object id“充当键),例如

代码语言:javascript
复制
class MyThing:
    def __init__(self,name,location,length):
            self.name = name
            self.location = location
            self.length = length

我希望使用MyThing的键,如果名称和位置相同,则被视为相同的键。从C#/Java开始,我习惯了重写并提供equals和hashcode方法,并承诺不会改变hashcode所依赖的任何东西。

我必须在Python中做什么才能做到这一点?我应该这样做吗?

(在一个简单的例子中,比如这里,也许把一个(name,location)元组作为key会更好--但是考虑到我希望key是一个对象)

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-02-05 02:55:44

您需要添加2 methods,请注意__hash____eq__

代码语言:javascript
复制
class MyThing:
    def __init__(self,name,location,length):
        self.name = name
        self.location = location
        self.length = length

    def __hash__(self):
        return hash((self.name, self.location))

    def __eq__(self, other):
        return (self.name, self.location) == (other.name, other.location)

    def __ne__(self, other):
        # Not strictly necessary, but to avoid having both x==y and x!=y
        # True at the same time
        return not(self == other)

Python dict documentation在关键对象上定义了这些要求,即它们必须是hashable

票数 256
EN

Stack Overflow用户

发布于 2011-02-05 04:58:30

Python2.6或更高版本中的另一种选择是使用collections.namedtuple() --它省去了编写任何特殊方法的麻烦:

代码语言:javascript
复制
from collections import namedtuple
MyThingBase = namedtuple("MyThingBase", ["name", "location"])
class MyThing(MyThingBase):
    def __new__(cls, name, location, length):
        obj = MyThingBase.__new__(cls, name, location)
        obj.length = length
        return obj

a = MyThing("a", "here", 10)
b = MyThing("a", "here", 20)
c = MyThing("c", "there", 10)
a == b
# True
hash(a) == hash(b)
# True
a == c
# False
票数 35
EN

Stack Overflow用户

发布于 2021-07-30 17:36:32

我注意到在Python3.8.8(可能是更早的版本)中,你不再需要显式地声明__eq__()__hash__(),这样就有机会使用你自己的类作为dict中的一个键。

代码语言:javascript
复制
class Apple:
    def __init__(self, weight):
        self.weight = weight
        
    def __repr__(self):
        return f'Apple({self.weight})'

apple_a = Apple(1)
apple_b = Apple(1)
apple_c = Apple(2)

apple_dictionary = {apple_a : 3, apple_b : 4, apple_c : 5}

print(apple_dictionary[apple_a])  # 3
print(apple_dictionary)  # {Apple(1): 3, Apple(1): 4, Apple(2): 5}

我假设从一段时间以来,Python会自己管理它,但是我可能错了。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4901815

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档