Как создать уникальный ключ для словаря в 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, порядок сортировки зависит от локали и т. д. но я думаю, это может быть хорошо. достаточно.