是否有一种可以无缝组合字典(将嵌套字典或列表作为值)和堆的Python数据 struct ,从而允许根据嵌套 struct 中的特定值进行排序?

cache = {"key1": {"time": time1, "info": "key1 info"}, "key2": {"time": time2, "info": "key2 info"}, ...}

或者:

cache = {"key1": [time1, "key1 info"], "key2": [time2, "key2 info"], ...}

这里是time1,time2,...是插入或更新条目的时间.

目标是实现高效的缓存,判断键的存在,验证值的 fresh 度(随着时间的推移它变得过时),并在缓存满时删除最旧的键.字典应该通过使用嵌套键"time"或列表的第0个元素来支持堆操作.

考虑的当前选项:

  1. 从字典形成一个堆(缺点-昂贵的操作O(n^2)).
  2. 使用分开存储的堆和字典实现一个类(缺点是在堆和字典中同步数据的复杂性).
  3. 简单迭代O(N)中的字典.此选项因其简单性而备受青睐,但可能不是最佳 Select .

有没有更有效的解决方案或避免创建自定义数据 struct 的不同方法?

推荐答案

Pythondict已经按插入顺序排序(在旧版本中,使用collections.OrderedDict),类似于按时间排序的堆.这意味着最早插入的项目始终位于最前面.不是更新值,而是移除并插入项目,以强制将更新的项目移到后面.

要使用dict作为基于时间的缓存,请使用以下方法.您可以将其转换为单独的子类、提供帮助器函数或内联添加代码.子类更好,可以避免误用,但涉及许多特殊方法,因此我将展示更简单的助手函数,并假定给定了生存时间(ttl).

  • 条目的格式应为"key": (time, value).具有不变的值(即tupleNamedTuple)以防止使有效time的约束无效是有利的.
  • 插入时,删除同一密钥以前的所有项.这会强制将项目插入到最后位置.
    def set(cache, key, value):
         cache.pop(key, None)  # clear the previous position if any
         cache[key] = (time.monotonic(), value))
    
  • 在进入时,只需查看时间即可.为了提高效率,您可能希望在访问时直接清除过期的密钥.
    def get(cache, key):
         key_time, value = cache[key]
         if key_time < time.monotonic() + ttl:  # check timestamp validity
             del cache[key]
             raise KeyError(key)
         return value
    
  • 要驱逐最旧的项,只需获取第一个密钥并删除它.
    def free(cache):
         if cache:
            oldest_key = next(iter(cache))
            del cache[oldest_key]
    
  • 要清除所有过时的项,只需迭代直到第一个键仍然有效.
    def clean(cache):
         outdated, deadline = [], time.monotonic() + ttl
         for key, (key_time, _) in cache.items():
             if key_time < deadline:
                 outdated.append(key)
             else:  # all following keys are valid as well
                 break
         for key in outdated:
             del cache[key]
    

Python相关问答推荐

我在使用fill_between()将最大和最小带应用到我的图表中时遇到问题

滚动和,句号来自Pandas列

使用索引列表列表对列进行切片并获取行方向的向量长度

无法定位元素错误404

为什么以这种方式调用pd.ExcelWriter会创建无效的文件格式或扩展名?

将9个3x3矩阵按特定顺序排列成9x9矩阵

Python逻辑操作作为Pandas中的条件

幂集,其中每个元素可以是正或负""""

python panda ExcelWriter切换动态公式到数组公式

寻找Regex模式返回与我当前函数类似的结果

搜索按钮不工作,Python tkinter

如何将一组组合框重置回无 Select tkinter?

在Python中控制列表中的数据步长

如何使用Azure Function将xlsb转换为xlsx?

Pandas:计数器的滚动和,复位

PYTHON中的pd.wide_to_long比较慢

将索引表转换为Numy数组

对列中的数字进行迭代,得到n次重复开始的第一个行号

使用元组扩展字典的产品挑战

Python键盘模块不会立即检测到按键