Есть ли лучший способ создать ключ словаря в python, чем преобразование в строку?

#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