Python字典键除了字符串和整数还有什么?

48 投票
5 回答
82044 浏览
提问于 2025-04-16 07:59

有没有人分享一些有趣的字典例子,里面用了一些特别的键(除了常见的字符串或整数),以及你是怎么在程序中使用这些键的?

我明白,作为键,我们需要的东西是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 错误,等等。

撰写回答