Python cache dictionary - hit count

I am doing caching in python. I still use a simple dictionary. What I would like to do is count the number of hits (the number of times the stored value has been extracted with the key). Python's builtin dict does not have this capability (as far as I know). I searched for “python word count” and found Counter(also on stackoverflow), but this does not meet my requirements, I think. I do not need to assume that already exists. I need to increase what comes from outside. And I think that saving another dictionary with hit counts is not the best data structure I can get :)

Do you have any idea how to do this efficiently?

+4
source share
5 answers

Having another dictionary for storing hit counts is probably not a bad option, but you can also do something like:

class CacheService(object):

    def __init__(self):
        self.data = {}

    def __setitem__(self, key, item):
        self.data[key] = [item, 0]

    def __getitem__(self, key):
        value = self.data[key]
        value[1] += 1
        return value[0]

    def getcount(self, key):
        return self.data[key][1]

You can use it something like this:

>>> cs = CacheService()
>>> cs[1] = 'one'
>>> cs[2] = 'two'
>>> print cs.getcount(1)
0
>>> cs[1]
'one'
>>> print cs.getcount(1)
1
+1
source

You can subclass the built-in class dict:

class CustomDict(dict):
    def __init__(self, *args, **kwargs):
        self.hits = {}
        super(CustomDict, self).__init__(*args, **kwargs)

    def __getitem__(self, key):
        if key not in self.hits:
            self.hits[key] = 0
        self.hits[key] += 1
        return super(CustomDict, self).__getitem__(key)

using:

>>> d = CustomDict()
>>> d["test"] = "test"
>>> d["test"]
'test'
>>> d["test"]
'test'
>>> d.hits["test"]
2
+3
source

, Python 3 ( Python 2, ), lru_cache.

docs . , :

from functools import lru_cache

@lru_cache(maxsize=32)
def meth(a, b):
    print("Taking some time", a, b)
    return a + b

print(meth(2, 3))
print(meth(2, 4))
print(meth(2, 3))

... :

Taking some time 2 3
5
Taking some time 2 4
6
5   <--- Notice that this function result is cached

meth.cache_info() meth.cache_clear().

+3

dict. .

def CountDict(dict):
    count = {}

    def __getitem__(self, key):
        CountDict.count[key] = CountDict.count.get(key, 0) + 1
        return super(CountDict, self).__getitem__(self, key)

    def __setitem__(self, key, value):
        return super(CountDict, self).__setitem__(self, key, value)

    def get_count(self, key):
        return CountDict.count.get(key, 0)

. : , - , . , . .

OP . get_count.

>>>my_dict = CountDict()
>>>my_dict["a"] = 1
>>>my_dict["a"]
>>>1
>>>my_dict["a"]
>>>1
>>>my_dict.get_count("a")
>>>2
0

: kids.cache

, kids.cache, , dict , .

>>> from kids.cache import cache

>>> @cache
... def meth(a, b):
...     print("Taking some time", a, b)
...     return a + b

:

>>> meth(1, 2)        ## Miss !
Taking some time 1 2
3
>>> meth(1, 2)        ## Hit !
3

:

>>> meth(1, 3)        ## Miss !
Taking some time 1 2
4

:

>>> meth.cache_info()
CacheInfo(type='dict', hits=1, misses=2, maxsize=None, currsize=2)

kids.cache, , . , . , .

, , ( , dict), . , cachetools.

Perhaps you can also use out of the box kids.cache, which has extensive documents . It has no dependency, only one file running on python2 and python3 is easy to use, allowing complex caching if necessary.

0
source

All Articles