Python字典键除了字符串和整数还有什么?
有没有人分享一些有趣的字典例子,里面用了一些特别的键(除了常见的字符串或整数),以及你是怎么在程序中使用这些键的?
我明白,作为键,我们需要的东西是hashable
,这意味着它必须是不可变的,并且可以进行比较(有__eq__()
或__cmp__()
方法)。
还有一个相关的问题是:我怎么能快速而简单地定义一个新的hashable
?
5 个回答
16
你漏掉了一个可能是最重要的方法,让一个对象变得可哈希:__hash__()
。
自己实现一个可哈希类型的最简单方法是这样的:
class A(object):
pass
现在你可以把A
的实例用作字典的键了:
d = {}
a = A()
b = A()
d[a] = 7
d[b] = 8
这是因为用户自定义的类默认是可哈希的,它们的哈希值就是它们的ID——所以只有当它们是同一个对象时,才会被认为是相等的。
需要注意的是,A
的实例并不是不可变的,但它们仍然可以用作字典的键。字典键必须不可变的说法只适用于内置类型。
18
你可以把元组当作键来用,比如说如果你想创建一个多列索引。这里有个简单的例子:
>>> index = {("John", "Smith", "1972/01/01"): 123, ("Bob", "Smith", "1972/01/02"): 124}
>>> index
{('Bob', 'Smith', '1972/01/02'): 124, ('John', 'Smith', '1972/01/01'): 123}
>>> index.keys()
[('Bob', 'Smith', '1972/01/02'), ('John', 'Smith', '1972/01/01')]
>>> index['John', 'Smith', '1972/01/01']
123
如果你想看看怎么把字典作为键(一个可哈希的字典),可以参考这个回答: Python 可哈希字典
42
我们来聊点稍微复杂一点的事情。假设你想要执行一系列的函数,并且把每个函数的结果都存起来。如果某个函数出错了,你还想记录下这个错误,并且统计每种错误出现的次数。函数和错误都可以用作 dict
的键,所以这件事其实很简单:
funclist = [foo, bar, baz, quux]
results = {}
badfuncs = {}
errorcount = {}
for f in funclist:
try:
results[f] = f()
except Exception as e:
badfuncs[f] = e
errorcount[type(e)] = errorcount[type(e)] + 1 if type(e) in errorcount else 1
现在你可以用 if foo in badfuncs
来检查这个函数是否出错了(或者用 if foo in results
来看看它是否正常运行),还可以用 if ValueError in errorcount
来查看有没有函数抛出过 ValueError
错误,等等。