Return 如果在 defaultdict 中找不到键,则最大键的值

Return value of largest key if key not found in defaultdict

要求

我想定义一个 defaultdict,如果我提供的键不在字典中,则 return 是最大键的值。基本上我正在寻找一种存储配置信息的方法,该值默认为其最后定义的值。

目前的解决方案

我的实现如下:

from collections import defaultdict

d = defaultdict(lambda: d[max(d.keys())])
d.update({2010: 10, 2011: 20, 2013: 30 })

for year in [2010, 2011, 2013, 2014]:
    print(f"{year}: {d[year]}")

正确生成:

2010: 10
2011: 20
2013: 30
2014: 30

(更复杂的版本也可以 return 小于最小键的值)。

问题

有没有更优雅的方法来定义 lambda 函数而不需要知道字典的名称?

不确定您是否需要在此处使用 defaultdictdefaultdict 的主要用途是在未找到请求的键时插入和设置默认值。然而在原题中,似乎不需要这个功能。

相反,我会使用自定义词典:

class CustomDict(dict):
    def __getitem__(self, key):
        if key not in self.keys():
            key = max(self.keys())
        return super().__getitem__(key)

如果您出于某种原因确实需要 defaultdict,您可以进行类似的操作并从 defaultdict.

派生

频繁计算最大键看起来效率很低,因为在 Python 中键位于哈希映射中,因此它们没有排序。

考虑自己编写 default_dict:

class DictLast(collections.MutableMapping,dict):
    def __init__(self, *args, **kwargs):
        self.theMaxKey = None 
        self.update(*args, **kwargs)
    def __getitem__(self, key):
        if dict.__contains__(self,key): 
            return dict.__getitem__(self,key)
        return dict.__getitem__(self, self.theMaxKey)
    def __setitem__(self, key, value):
        if self.theMaxKey is None:
            self.theMaxKey = key
        if key > self.theMaxKey: 
            self.theMaxKey = key
        dict.__setitem__(self,key,value)   

d = DictLast()
d.update({2010: 10, 2011: 20, 2013: 30 })

for year in [2010, 2011, 2013, 2014]:
    print(f"{year}: {d[year]}")

请注意,每当被要求提供丢失的钥匙时, 我的实现没有将键添加到字典中。我认为这是预期的行为

如果您有疑问,请在我的和您的实现中尝试此代码:

for year in [2010, 2011, 2013, 2015]:
    print(f"{year}: {d[year]}")
d[2014]=7
for year in [2010, 2011, 2013, 2015]:
    print(f"{year}: {d[year]}")

了解有什么区别

编辑: 正如以下评论中指出的那样:

“此策略仅在您不从字典中删除项目时才有效”。

IMO 如果你希望数据结构设计得很好,你也应该管理删除(由你决定是否要加注,重新计算最大值或做一些不同的事情)。