如何使用函数从不存在的键自动创建值
How to automatically create value from non existing key with a function
背景:
假设我有一个函数(当然实际上这会是一个更复杂的函数):
def f(x):
return str(x)
如果我想存储值以避免不必要的重新计算,我可以像这样创建一个 dict
:
my_dict = {x: f(x) for x in range(5)}
但是如果我事先不知道我可能需要哪些值,例如 10
,my_dict[10]
显然会生成 KeyError
。
解决这个问题的一种方法是:
my_dict = {}
def get_value(x):
if x not in my_dict:
my_dict[x] = f(x)
return my_dict[x]
get_value(10)
问题:
这似乎与 defaultdict
非常相似:有没有办法使直观的(但损坏的)my_dict = defaultdict(f)
工作,即当键 x
不存在时,它应该调用 f(x)
而不是 f()
来创建默认值?
基于 the docs,您可以通过继承 defaultdict
并覆盖 __missing__
:
来获得您想要的行为
from collections import defaultdict
class betterdefault(defaultdict):
def __missing__(self, key):
return self.default_factory(key)
现在,你想用一些额外的逻辑来充实它,例如,如果 self.default_factory
是 None,则抛出 KeyError
,就像他们在文档中提到的那样.希望这能为您指明正确的方向。
这是一个快速的 demo
您可以构建自己的 dict
数据类型。在您的情况下,__missing__
会有所帮助。如果没有密钥,__missing__
方法会触发您的自定义工作。下面是一个简单的例子。
from collections import UserDict
class MyDict(UserDict):
def __missing__(self, key):
self[key] = 2*key
return self[key]
if __name__ == '__main__': # test
a = MyDict((x, 2*x) for x in range(5))
print(a)
# {0: 0, 1: 2, 2: 4, 3: 6, 4: 8}
a[5]
# 10
print(a)
# {0: 0, 1: 2, 2: 4, 3: 6, 4: 8, 5:10}
另请注意,UserDict
是字典对象的包装器,使您可以轻松地对字典数据类型进行子类化。
查看官方文档。
背景:
假设我有一个函数(当然实际上这会是一个更复杂的函数):
def f(x):
return str(x)
如果我想存储值以避免不必要的重新计算,我可以像这样创建一个 dict
:
my_dict = {x: f(x) for x in range(5)}
但是如果我事先不知道我可能需要哪些值,例如 10
,my_dict[10]
显然会生成 KeyError
。
解决这个问题的一种方法是:
my_dict = {}
def get_value(x):
if x not in my_dict:
my_dict[x] = f(x)
return my_dict[x]
get_value(10)
问题:
这似乎与 defaultdict
非常相似:有没有办法使直观的(但损坏的)my_dict = defaultdict(f)
工作,即当键 x
不存在时,它应该调用 f(x)
而不是 f()
来创建默认值?
基于 the docs,您可以通过继承 defaultdict
并覆盖 __missing__
:
from collections import defaultdict
class betterdefault(defaultdict):
def __missing__(self, key):
return self.default_factory(key)
现在,你想用一些额外的逻辑来充实它,例如,如果 self.default_factory
是 None,则抛出 KeyError
,就像他们在文档中提到的那样.希望这能为您指明正确的方向。
这是一个快速的 demo
您可以构建自己的 dict
数据类型。在您的情况下,__missing__
会有所帮助。如果没有密钥,__missing__
方法会触发您的自定义工作。下面是一个简单的例子。
from collections import UserDict
class MyDict(UserDict):
def __missing__(self, key):
self[key] = 2*key
return self[key]
if __name__ == '__main__': # test
a = MyDict((x, 2*x) for x in range(5))
print(a)
# {0: 0, 1: 2, 2: 4, 3: 6, 4: 8}
a[5]
# 10
print(a)
# {0: 0, 1: 2, 2: 4, 3: 6, 4: 8, 5:10}
另请注意,UserDict
是字典对象的包装器,使您可以轻松地对字典数据类型进行子类化。
查看官方文档。