Как создать уникальный ключ для словаря в Python
каков наилучший способ создания уникального ключа для содержимого словаря. Я намерен хранить каждый словарь в хранилище документов вместе с уникальным идентификатором или хэшем, чтобы мне не пришлось загружать весь словарь из магазина, чтобы проверить, существует ли он уже или нет. словари с теми же ключами и значениями должны генерировать тот же идентификатор или хэш.
у меня есть следующий код:
import hashlib
a={'name':'Danish', 'age':107}
b={'age':107, 'name':'Danish'}
print str(a)
print hashlib.sha1(str(a)).hexdigest()
print hashlib.sha1(str(b)).hexdigest()
последние два оператора печати генерируют та же струна. Это хорошая реализация? или есть какие-то подводные камни при таком подходе? Есть ли лучший способ сделать это?
обновление
объединение предложений из ответов ниже, следующее Может быть хорошей реализацией
import hashlib
a={'name':'Danish', 'age':107}
b={'age':107, 'name':'Danish'}
def get_id_for_dict(dict):
unique_str = ''.join(["'%s':'%s';"%(key, val) for (key, val) in sorted(dict.items())])
return hashlib.sha1(unique_str).hexdigest()
print get_id_for_dict(a)
print get_id_for_dict(b)
3 ответов
возможный вариант будет использовать сериализованное представление списка, которое сохраняет порядок. Я не уверен, что список по умолчанию для строкового механизма налагает какой-либо порядок, но меня не удивило бы, если бы он зависел от интерпретатора. Итак, я бы в основном построил что-то похожее на urlencode
Это сортирует ключи заранее.
Не то, чтобы я считаю, что ваш метод потерпит неудачу, но я бы предпочел играть с предсказуемыми вещами и избегать недокументированного и/или непредсказуемого поведения. Это правда, что, несмотря на" неупорядоченность", словари в конечном итоге имеют порядок, который может быть даже последовательным, но дело в том, что вы не должны принимать это как должное.
Я предпочитаю сериализацию Дикта как JSON и хэширование этого:
import hashlib
import json
a={'name':'Danish', 'age':107}
b={'age':107, 'name':'Danish'}
print hashlib.sha1(json.dumps(a, sort_keys=True)).hexdigest()
print hashlib.sha1(json.dumps(b, sort_keys=True)).hexdigest()
возвращает:
71083588011445f0e65e11c80524640668d3797d
71083588011445f0e65e11c80524640668d3797d
нет - вы не можете полагаться на определенный порядок элементов при преобразовании словаря в строку.
можно, однако, преобразовать его в отсортированный список (ключ,значение) кортежей, преобразовать его в строку и вычислить хэш вроде этого:
a_sorted_list = [(key, a[key]) for key in sorted(a.keys())]
print hashlib.sha1( str(a_sorted_list) ).hexdigest()
это не доказательство дурака, так как формирование списка, преобразованного в строку, или форматирование кортежа может измениться в какой-то будущей основной версии python, порядок сортировки зависит от локали и т. д. но я думаю, это может быть хорошо. достаточно.