#python #dictionary #key
#питон #словарь #Клавиша
Вопрос:
У меня есть функция, которая возвращает энергию, связанную с вектором в трехмерном пространстве, F(i, j, k) .
F() — медленная функция, поэтому у меня есть словарь, который проверяет, был ли вызван F() для определенного i, j, k, и если это так, я просто беру это значение из словаря.
В настоящее время я делаю это как:
key = "_".join( [ str(i), str(j), str(k) ])
if key not in dic:
dic[key] = F(i,j,k)
Energy = dic[key]
Есть ли лучший способ создать ключ, чем путем объединения векторов, подобных этому?
Комментарии:
1. Для дальнейшего использования эту первую строку можно упростить, используя
map
, чтобыkey = "_".join(map(str, (i, j, k)))
Ответ №1:
Ключи словаря могут быть любыми хэшируемыми; кортеж из 3 значений подходит:
key = i, j, k # a comma makes this a tuple
try:
Energy = dic[key]
except KeyError:
Energy = dic[key] = F(i, j, k)
Здесь я использую обработку исключений (прошу прощения), а не явно проверяю, присутствует ли ключ (запрашиваю разрешение); первое выполняется быстрее, когда отсутствие ключа является нормой.
Комментарии:
1. Я использовал стеллаж для хранения своих словарей. Очевидно, это не будет работать с кортежами в качестве ключей. Является ли маринованный огурец следующей лучшей альтернативой?
2.@egoburnswell:
shelve
использует pickle в качестве реализации. Ключи кортежей должны отлично работать с shelve; какую ошибку вы видите?3. ‘Ошибка типа: ожидаемый объект String или Integer для ключа, найден кортеж’
4. @egoburnswell: Мои извинения, я действительно вижу, что
shelve
документально подтверждено, что в качестве ключей принимаются только строки. Это потому, что значения выбираются, но затем они сохраняются в файле в стиле DBM , и именно этот формат ограничивает ваши ключи.5. @egoburnswell: либо сохраните свой словарь, вложенный в
shelve
(shelveobj['data'] = yourdict
, не забудьте переназначить этот ключ при изменениях ), либо используйте только Pickle, в этом случае.
Ответ №2:
Поскольку Python dicts может принимать любой хешируемый объект в качестве ключей [1], вы можете просто использовать (i, j, k)
кортеж:
if (i, j, k) not in dic:
dic[(i, j, k)] = F(i,j,k)
Energy = dic[(i, j, k)]
[1] https://docs.python.org/2/library/stdtypes.html#mapping-types-dict