Python equivalent of Scala's lazy val
python, scala
Solution
In Scala, `lazy val` is a final variable that is evaluated once at the time it is first accessed, rather than at the time it is declared. It is essentially a memoized function with no arguments. Here's one way you can implement a memoization decorator in Python:
from functools import wraps
def memoize(f):
@wraps(f)
def memoized(*args, **kwargs):
key = (args, tuple(sorted(kwargs.items()))) # make args hashable
result = memoized._cache.get(key, None)
if result is None:
result = f(*args, **kwargs)
memoized._cache[key] = result
return result
memoized._cache = {}
return memoized
Here's how it can be used. With `property` you can even drop the empty parentheses, just like Scala:
>>> class Foo:
... @property
... @memoize
... def my_lazy_val(self):
... print "calculating"
... return "some expensive value"
>>> a = Foo()
>>> a.my_lazy_val
calculating
'some expensive value'
>>> a.my_lazy_val
'some expensive value'
Problem
I'm currently trying to port some Scala code to a Python project and I came across the following bit of Scala code: ``` lazy val numNonZero = weights.filter { case (k,w) => w > 0 }.keys ``` `weights` is a really long list of tuples of items and their associated probability weighting. Elements are frequently added and removed from this list but checking how many elements have a non-zero probability is relatively rare. There are a few other rare-but-expensive operations like this in the code I'm porting that seem to benefit greatly from usage of `lazy val`. What is the most idiomatic Python way to do something similar to Scala's `lazy val`?