Python缓存创建的列表

时间:2018-11-05 14:39:06

标签: python python-3.x

我必须编写一个获取三个参数的函数。较低,较高的缓存。 较低和较高给出创建新列表的范围。这部分是这段代码:

def one_range(lower, higher, cache):
    list1 = []
    for i in range(lower,higher):
        list1.append(i)
    return list1    

如果使用相同的参数两次调用了“ range”,则两次都应返回相同的列表。列表第二次不再生成,而是重新使用。 我该怎么办?

编辑了原始功能

2 个答案:

答案 0 :(得分:3)

假设cache是一个字典,您可以从其他参数中创建一个tuple并查看该元组是否在字典中。如果是,则从dict返回值,否则计算该值并将其存储在dict中,然后再返回。您可能还提供了cache的默认值,因此也可以不使用该功能。

def one_range(lower, higher, cache=None):
    if cache is not None and (lower, higher) in cache:
        return cache[(lower, higher)]
    lst = []
    for i in range(lower,higher):
        lst.append(i)
    if cache is not None:
        cache[(lower, higher)] = lst
    return lst

示例:

c = {}
x = one_range(2, 4, c)
y = one_range(1, 4, c)
z = one_range(2, 4, c)
print(x is z) # True
print(c)      # {(2, 4): [2, 3], (1, 4): [1, 2, 3]}

尽管很多,但使功能混乱。实际上,使用函数装饰器可以轻松完成此操作。如果您不能使用functools.lru_cache,则只需几行代码即可实现自己的备忘录装饰器:

def memo(f):
    f.cache = {}
    def _f(*args, **kwargs):
        if args not in f.cache:
            f.cache[args] = f(*args, **kwargs)
        return f.cache[args]
    return _f

然后在函数中使用它,而无需使用不再需要的cache参数:

@memo
def one_range(lower, higher):
    lst = []
    for i in range(lower,higher):
        lst.append(i)
    return lst

答案 1 :(得分:2)

假设您的参数是可哈希的,则可以使用functools.lru_cache()(Python 3.2+)来实现:

import functools

@functools.lru_cache(maxsize=128)
def mrange(lower, higher):
    print('mrange was called')
    res = []
    for i in range(lower, higher):
        res.append(i)
    return res 

小点:

  • 词典用于缓存结果,因此为什么位置参数和关键字参数都必须是可哈希的。
  • 尝试避免使用阴影(掩盖)现有内置名称的名称来命名对象,例如rangelist
  • 使用mrange.cache_clear()清除缓存。

示例:

>>> mrange(1, 10)
mrange was called
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> mrange(1, 10)
[1, 2, 3, 4, 5, 6, 7, 8, 9]