字典值的惰性评估?
Lazy evaluation of dict values?
假设我有以下字典 d={'a': heavy_expression1, 'b': heavy_expression2}
.
如何包装表达式,以便在访问它们时对其进行求值,之后不执行求值?
d['a'] # only here heavy_expression1 is executed
d['a'] # no execution here, already calculated
我需要使用 lambda
还是生成器?
带有 lambda 的版本:
class LazyDict(dict):
def __init__(self, lazies):
self.lazies = lazies
def __missing__(self, key):
value = self[key] = self.lazies[key]()
return value
d = LazyDict({'a': lambda: print('heavy_expression1') or 1,
'b': lambda: print('heavy_expression2') or 2})
print(d['a'])
print(d['a'])
print(d['b'])
print(d['b'])
输出:
heavy_expression1
1
1
heavy_expression2
2
2
另一种方法是中断子类中的 __getitem__
方法并在那里进行缓存:
class LazyDict(dict):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.cache = {}
def __getitem__(self, item):
if item in self.cache:
return self.cache[item]
result = super().__getitem__(item)()
self.cache[item] = result
return result
这是带有函数的测试用例:(lambda 如果您不想定义函数,这里非常适合)
def heavy_expresion1():
print('heavy expression1 is calculated')
return 10
def heavy_expresion2():
print('heavy expression2 is calculated')
return 20
d = LazyDict({'a': heavy_expresion1, 'b': heavy_expresion2})
print(d)
print(d['a'])
print(d['a'])
print(d['b'])
print(d['b'])
输出:
{'a': <function heavy_expresion1 at 0x000001AFE783ED30>, 'b': <function heavy_expresion2 at 0x000001AFE8036940>}
heavy expression1 is calculated
10
10
heavy expression2 is calculated
20
20
假设我有以下字典 d={'a': heavy_expression1, 'b': heavy_expression2}
.
如何包装表达式,以便在访问它们时对其进行求值,之后不执行求值?
d['a'] # only here heavy_expression1 is executed
d['a'] # no execution here, already calculated
我需要使用 lambda
还是生成器?
带有 lambda 的版本:
class LazyDict(dict):
def __init__(self, lazies):
self.lazies = lazies
def __missing__(self, key):
value = self[key] = self.lazies[key]()
return value
d = LazyDict({'a': lambda: print('heavy_expression1') or 1,
'b': lambda: print('heavy_expression2') or 2})
print(d['a'])
print(d['a'])
print(d['b'])
print(d['b'])
输出:
heavy_expression1
1
1
heavy_expression2
2
2
另一种方法是中断子类中的 __getitem__
方法并在那里进行缓存:
class LazyDict(dict):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.cache = {}
def __getitem__(self, item):
if item in self.cache:
return self.cache[item]
result = super().__getitem__(item)()
self.cache[item] = result
return result
这是带有函数的测试用例:(lambda 如果您不想定义函数,这里非常适合)
def heavy_expresion1():
print('heavy expression1 is calculated')
return 10
def heavy_expresion2():
print('heavy expression2 is calculated')
return 20
d = LazyDict({'a': heavy_expresion1, 'b': heavy_expresion2})
print(d)
print(d['a'])
print(d['a'])
print(d['b'])
print(d['b'])
输出:
{'a': <function heavy_expresion1 at 0x000001AFE783ED30>, 'b': <function heavy_expresion2 at 0x000001AFE8036940>}
heavy expression1 is calculated
10
10
heavy expression2 is calculated
20
20