Существует ли структура данных Python, которая легко объединяет словарь (с вложенными словарями или списками в качестве значений) и кучу, позволяя сортировать на основе определенного значения внутри вложенных структур?
cache = {"key1": {"time": time1, "info": "key1 info"}, "key2": {"time": time2, "info": "key2 info"}, ...}
или:
cache = {"key1": [time1, "key1 info"], "key2": [time2, "key2 info"], ...}
здесь time1, time2, ... — время вставки или обновления записи.
Цель состоит в том, чтобы реализовать эффективный кеш, проверяя существование ключа, проверяя актуальность значения (поскольку оно устаревает с течением времени) и удаляя самый старый ключ, когда кеш заполнен. Словарь должен поддерживать операции с кучей либо с использованием вложенного ключа «время», либо с использованием нулевого элемента списка.
Рассматриваемые текущие варианты:
Есть ли более эффективное решение или другой подход, позволяющий избежать создания собственной структуры данных?
@trincot, спасибо за ответ и вопрос. временная часть всегда является текущим временем (время вставки или обновления). Но я не понял, что касается хронологического времени. Что ты имеешь в виду?
Я имею в виду: может ли когда-нибудь случиться, что вы добавите в dict пару time,info, которая равна [5, «info1»], а затем (позже) добавите пару, которая будет [4, «info2»]], так что где второй раз меньше первого? Я понимаю, что это не так и значения времени никогда не уменьшаются, а «хронологические» (увеличиваются временные метки).
Я не могу изменить историю, конечно
Что конкретно вам нужно из кучи? Вставка Python dict уже заказана, поэтому получить самый старый или самый новый элемент не составит труда.
сейчас напишу ответ...
@МистерМияги, ты! 1. Я не знал, что, поскольку порядок LIFO в Python 3.7 гарантирован в методе popitem() dict 2. Кажется, что OrderedDict и его popitem(last=False) - это то, что мне нужно (docs.python.org/3/ библиотека/…) Пожалуйста, не останавливайтесь, если пишете ответ!






В Python dict уже упорядочена вставка (в старых версиях используйте collections.OrderedDict), аналогично куче, отсортированной по времени. Это означает, что самый старый вставленный элемент всегда находится впереди. Вместо обновления значений удалите и вставьте элемент, чтобы принудительно переместить обновленные элементы назад.
Чтобы использовать dict в качестве временного кеша, используйте следующий подход. Вы можете выделить его в отдельный подкласс, предоставить вспомогательные функции или добавить встроенный код. Подкласс удобнее и позволяет избежать неправильного использования, но включает в себя множество специальных методов, поэтому я покажу более простые вспомогательные функции и предположу, что время жизни (ttl) задано.
"key": (time, value). Выгодно иметь неизменяемые значения (т. е. tuple или NamedTuple), чтобы предотвратить аннулирование ограничения действительного 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]
всегда ли часть времени является текущим временем или, иначе говоря: всегда ли вставки/обновления элементов dict имеют хронологическое время? Или есть обновления, которые "меняют историю"?