Скажите, что у меня есть поток входящих элементов, которые я обрабатываю. Для каждого элемента я извлекаю некоторые данные и сохраняю их. Но много предметов одинаково. Я хочу отслеживать их получение, но не хранить одни и те же данные более одного раза. Я могу реализовать это так, но это кажется неуклюжим:Нормально ли использовать объект в качестве собственного ключа в словаре/hashmap (в python)?
item_cache = {}
item_record = []
def process(input_item):
item = Item(input_item) # implements __hash__
try:
item_record.append(item_cache[item])
except KeyError:
item_cache[item] = item # this is the part that seems weird
item_record.append(item)
Я просто переусердствовал это? Делает d[thing] = thing
довольно нормальную конструкцию в python?
EDIT
В ответ на комментарий ниже. Вот более полный пример, показывающий, как этот код позволяет избежать дублирования копий входных данных.
class Item(object):
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
def __eq__(self, other):
return self.a == other.a and self.b == other.b and self.c == other.c
def __ne__(self, other):
return not (self == other)
def __hash__(self):
return hash((self.a, self.b, self.c))
def __repr__(self):
return '(%s, %s, %s)' % (self.a, self.b, self.c)
item_cache = {}
item_record = []
def process_item(new_item):
item = Item(*new_item)
try:
item_record.append(item_cache[item])
except KeyError:
item_cache[item] = item
item_record.append(item)
del item # this happens anyway, just adding for clarity.
for item in ((1, 2, 3), (2, 3, 4), (1, 2, 3), (2, 3, 4)):
process_item(item)
print([id(item) for item in item_record])
print(item_record)
Если 'thing' является неизменным (и это должно быть, иначе вы не можете использовать его в качестве ключа), возможно,' set() 'является лучшим контейнером для кеша? – DyZ
Из контекста, будет ли лучше использовать какое-либо свойство объекта как ключевое слово item.some_unique_id (может быть кортеж/составной из других свойств) , который уже хешируется и, надеюсь, неизменен? –