你可以定义一个字典的子类来访问字典条目,并使用虚拟默认值来应用于任何不存在的键,但在引用它们时不会实际创建任何键(与setdefault()函数相反)。
class dictWithDefault(dict):
def __init__(self,aDict={},defaultValue=None):
super().__init__(aDict)
def aFunction():pass
self._default = defaultValue if type(defaultValue) == type(aFunction) else lambda : defaultValue
def __getitem__(self,key):
return super().__getitem__(key) if key in self else self._default()
d = {1:2, 3:4, 5:6}
d = dictWithDefault(d,99)
d[1]
d[7]
d[7] = 97
d[7]
d._default = 100
d[9]
d[8] += 5
d[8]
d
你可以直接创建一个带有默认值的字典:
d = dictWithDefault({1:2, 3:4, 5:6},99)
如果想要使用默认键而不是默认值,您可以使用相同的技术,只需更改getitem方法的实现。
或者,您可以简单地使用d = dictWithDefault(d)而不使用默认值,并使用or运算符来获取替代键:
d = dictWithDefault(d)
value = d[7] or d[5]
[编辑] 更改了代码以支持对象作为默认值。
当在字典中使用对象(例如列表)作为值时,您必须小心。在第一次隐式赋值给新键时,它将仅被赋予对 _default 对象的引用。这意味着所有这些键最终都会引用相同的对象。
例如:d = dictWithDefault(defaultValue=[]) 将不能按预期工作。
d = dictWithDefault(defaultValue=[])
d["A"].append(1)
d["B"].append(2)
为了解决这个问题,我改变了函数的定义方式,使其可以接受一个lambda表达式:在使用对象作为默认值的情况下。
这样可以使默认值在用于新键时创建一个新实例。
d = dictWithDefault(defaultValue=lambda:[])
d["A"].append(1)
d["B"].append(2)
对于简单类型(如字符串、整数等),您仍然可以在没有lambda的情况下使用该类,但是必须确保在字典将对象存储为值时使用实例创建方法与lambda一起使用。
d.get(val, a.get(def_key))
已经足够好了。 - Alex Halla.get
而不是d.get
...? - user202729dict
的子类,并添加这样一个方法。 - Jean-François Fabre