用类作字典的 Key 能搞不?

2017-07-26 11:38:01 +08:00
 bccber
class Key:
def __init__(self, i, j):
self.i = i
self.j = j
pass

dic={};

key1 = Key(1, 1)
key2 = Key(1, 1)

dic.append(key1, 1)
dic.append(key2, 1)
4696 次点击
所在节点    Python
22 条回复
fox0001
2017-07-26 12:01:33 +08:00
那要 key 来干嘛?
wwqgtxx
2017-07-26 12:10:34 +08:00
当然可以了
Python 3.6.1 (v3.6.1:69c0db5, Mar 21 2017, 18:41:36) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> class A:
... pass
...
>>> {A():1,A():2}
{<__main__.A object at 0x0000026C84DA32E8>: 1, <__main__.A object at 0x0000026C84DA3320>: 2}
>>>
pythongo
2017-07-26 12:17:45 +08:00
字典的 key 是不可变,能 hash 的, 你去看字典 key 的限制,只要符合规范当然可以
siteshen
2017-07-26 12:20:55 +08:00
1. 代码能不能跑?跑一下就知道了。
2. 为什么能(不能)跑?参考 3 楼的答案。
ivechan
2017-07-26 12:42:12 +08:00
能 hash 的都能.
bccber
2017-07-26 13:42:59 +08:00
@ivechan @pythongo @wwqgtxx
怎么处理碰撞?
当类的 i,j 字段不一样 但 hash 又一样时,怎么处理?
需要重写 HashCode?或者 Equals 方法吗?
HypoChen
2017-07-26 13:52:24 +08:00
bccber
2017-07-26 13:54:00 +08:00
def __hash__(self): 和 __eq__ ??
bccber
2017-07-26 13:54:18 +08:00
@HypoChen 你输了五毛
PythonAnswer
2017-07-26 14:00:24 +08:00
汽车能当钥匙使吗?能啊。但是有些浪费。
cy18
2017-07-26 14:03:35 +08:00
hash 是辅助判断的,主要是 eq。要确保 eq 的两个对象 hash 必须相等,反之不一定。
最坏情况,hash 全部返回 0 都没关系,只不过会导致速度很慢。
反之如果 hash 不等但是 eq 的话就会出问题。比如用 id 做 hash 然后用成员变量值判断 eq。
bccber
2017-07-26 14:04:54 +08:00
hash 只是为了快速判断
当 hash 一样 会使用 eq 再判断
是吧
bccber
2017-07-26 14:06:53 +08:00
ok 了
bccber
2017-07-26 14:07:48 +08:00
@PythonAnswer 你竟然没碰到过必须要使用类或者结构体作 key 的场景?
CryMeatel
2017-07-26 14:15:17 +08:00
@bccber 一般这样的需求,我都是直接把数据套入现成可 hash 化容器的,比如 tuple, namedtuple ;其实类作为 key 也是为了对其成员变量做个区分吧
bccber
2017-07-26 14:48:50 +08:00
@CryMeatel

我猜测 tuple 并不会处理 def __hash__(self): 和 __eq__
然后是使用 tuple 的地址作 key 这样有可能会出问题的
wwqgtxx
2017-07-26 17:12:08 +08:00
@bccber python 的 dict 并不考虑你的__hash__和__eq__,他是直接比较内存地址的
wwqgtxx
2017-07-26 18:12:47 +08:00
刚才没注意,python 的 dict 会考虑__eq__的,测试方法如下
>>> class A:
... def __hash__():
... return 1
...
>>>
>>> class A:
... def __hash__(self):
... return 1
... def __eq__(self,a):
... return True
...
>>> {A():1,A():2}
{<__main__.A object at 0x0000026C84DA3D30>: 2}
>>> class A:
... def __hash__(self):
... return 1
...
>>> {A():1,A():2}
{<__main__.A object at 0x0000026C84DA3320>: 1, <__main__.A object at 0x0000026C84DA3D68>: 2}
>>>
pythongo
2017-07-26 19:32:02 +08:00
A dictionary ’ s keys are almost arbitrary values. Values that are not hashable, that is, values containing lists, dictionaries or other mutable types (that are compared by value rather than by object identity) may not be used as keys.

hashable
An object is hashable if it has a hash value which never changes during its lifetime (it needs a __hash__() method), and can be compared to other objects (it needs an __eq__() or __cmp__() method). Hashable objects which compare equal must have the same hash value.

Hashability makes an object usable as a dictionary key and a set member, because these data structures use the hash value internally.

All of Python ’ s immutable built-in objects are hashable, while no mutable containers (such as lists or dictionaries) are. Objects which are instances of user-defined classes are hashable by default; they all compare unequal (except with themselves), and their hash value is derived from their id().
PythonAnswer
2017-07-26 19:54:17 +08:00
@bccber 没遇到过。并且你这个只是实例做 key。

key 应该尽量简化,value 则可以复杂些。个人愚见。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/378035

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX