基于键的 Python 字典默认值

4
我需要一个字典,当访问缺少的键时自动填充默认值。我找到了defaultdict和其他一些方法来实现这一点,但在我的情况下问题是我想让每个键的默认值特定于该键本身。
例如,使用defaultdict,我可以实现以下内容:
from collections import defaultdict
d = defaultdict(lambda: 5)
> d[1] = 3
> d[1]
> 3
> d[2]
> 5

但是如果我需要访问缺失的键的默认值为例如 key + 5,该怎么办呢?类似这样:

from collections import defaultdict
d = defaultdict(lambda key: key + 5)  # <-- This does not work as defaultdict expects lambda function to be without any parameters
> d[1] = 3
> d[1]
> 3
> d[2]
> 7         <- Calculated from accessed key + 5 (2+5)
> d[5]
> 10        <- Calculated from accessed key + 5 (5+5)

有没有一种干净、内置的方法可以实现我需要的功能?我知道可以创建字典的子类并在__getitem__级别上实现特定功能,但如果可能的话,我想避免这样做。

我在其他答案中找不到解决方案,如果仍然是重复,请原谅。


你为什么认为你目前的方式不够“简洁”? - Asocia
defaultdict 只能与没有参数的 lambda 函数一起使用,因此第二个示例不是有效的 Python 代码。 - Cxovrika
它只是展示了我想要最终实现的功能。 - Cxovrika
哦,好的。我以为这是当前的行为,你想要进一步的改进。 - Asocia
3个回答

7

我认为没有内置的方法可以完成这个功能。不过,你可以继承defaultdict,并且改变 __missing__() 方法,在调用 default_factory 方法时传入一个参数(即键名 key),而不是不带参数。虽然仍然是自定义类而不是内置类,但仍然应该非常高效。

from collections import defaultdict

class DefaultDict(defaultdict):
    def __missing__(self, key):
        return self.default_factory(key)

然后:

d = DefaultDict(lambda key: key + 5)

d[2]
# 7

1
尽管我想避免创建子类,但这似乎是目前最好的解决方案,所以我会接受这个答案,谢谢! - Cxovrika

1
你也可以使用这样的函数。
dic = {}
DEFAULT_VALUE = 5

def dict_get(item):
    try:
        return [dic[item]]
    except:
        dic[int(item)] = DEFAULT_VALUE + int(item)
        return DEFAULT_VALUE + int(item)

print(dict_get(10))

1
这种方法的问题在于,如果找不到键,就会对字典进行两次搜索:第一次是在尝试返回时搜索它,然后再插入键时再次搜索(这是默认行为:每当您尝试插入键时,字典首先检查键是否已经存在)。如果字典很大,这很重要。标准库中的defaultdict避免了这种双重搜索。 - Amenhotep

0

以下是如何在不创建任何类的情况下完成它。您可以使用dict.setdefault

d = {}
d_default_factory = lambda key: key + 5
d.setdefault(2, d_default_factory(2))
# 7

如果需要的话,您可以将默认工厂保存为字典中的一个条目,像这样:

d = {'default_factory': lambda key: key + 5}
d.setdefault(2, d['default_factory'](2))
# 7

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接