Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 是否为字典生成唯一标识符?_Python_Dictionary_Hash_Uniqueidentifier - Fatal编程技术网

Python 是否为字典生成唯一标识符?

Python 是否为字典生成唯一标识符?,python,dictionary,hash,uniqueidentifier,Python,Dictionary,Hash,Uniqueidentifier,我有一个问题,我随机生成一个字典,可能有很多可能性(比如,我有25000个可能不同的DIC)。我想为每一种可能性生成一个标识符,一个ID。我想要的是: 如果两个字典对每个键具有完全相同的值,则ID相同 如果两个词典具有不同的ID,则它们的内容必须至少有一个差异 每次运行程序时,ID都保持不变(ID(x)不工作) 好处:不同版本的Python(2.6、2.7、3.4、3.6)的ID保持不变 我目前的想法是使用散列函数(尽管我对它了解很少),并执行类似的操作(假设一个int/float数字字典)

我有一个问题,我随机生成一个字典,可能有很多可能性(比如,我有25000个可能不同的DIC)。我想为每一种可能性生成一个标识符,一个ID。我想要的是:

  • 如果两个字典对每个键具有完全相同的值,则ID相同
  • 如果两个词典具有不同的ID,则它们的内容必须至少有一个差异
  • 每次运行程序时,ID都保持不变(
    ID(x)
    不工作)
  • 好处:不同版本的Python(2.6、2.7、3.4、3.6)的ID保持不变
我目前的想法是使用散列函数(尽管我对它了解很少),并执行类似的操作(假设一个int/float数字字典):

据我所知,这在大多数情况下都是可行的,但根据字典和键的实际内容,两个不同的DIC产生相同的ID并非不可能。例如,如果我没有散列键,两个不同的条目可能是“1.0”,那么我可能会有问题

你有什么建议,希望不依赖运气


编辑:我添加了一个更大的代码在我试图做的事情上:它基本上是一个随机参数优化

要创建ID,您需要创建一个不可变的对象。 由于键是无序的,您可能需要对它们进行排序

例如:

mydict = {'a': 1, 'c': 9, 'b': 3}

values = tuple(sorted(mydict.items()))
# -> (('a', 1), ('b', 3), ('c', 9))
然后,您可以使用自己的哈希算法,例如sha256:

import hashlib

def hash_item(m, k, v):
    m.update(k.encode('utf-8'))
    m.update(str(k).encode('utf-8'))

m = hashlib.sha256()
for k, v in values:
    hash_item(m, k, v)
print(m.digest())
# -> b'\xa5\xb42\xee\x03\x07\xbe\x7f\xa2:\xa0\x04a\xf5N\xee4\xba\x9dE%\x1bU\x04V}7\xa8\xda3\x9d\xff'

靠运气;其他人这样做是有充分理由的。除非您的ID比您可以编码的最长词典长,或者您选择无法编码某些词典,否则将有多个具有相同ID的词典。这只是一个简单的计数问题。假设你说出一本字典1,另外两本,依此类推。要么你的号码用完了,要么你的身份证变长了。 一般来说,当我们需要一些小的数量来代表一个对象时,我们会使用id或hash。如果您希望词典的名称与词典本身一样大,那么您需要的是规范表示,而不是ID或哈希

类似sha256的优点是,我们认为很难找到具有相同哈希的两个输入。尽管理论上可以确定有多个输入提供相同的sha256,但我们相信还没有人找到两个输入提供相同的sha256。
因此,忽略会遇到哈希冲突的可能性,您几乎可以肯定是足够安全的。

您到底想实现什么?任何将大输入集映射到小输入集的哈希都会发生冲突。所以总是有一点“运气”的参与。你可以做的是:用你的id来比较dict。如果id不同,dict就不同。如果ID相同,请按值比较dicts。@tyteen4a03我有一个算法,我想在多组参数上进行测试。我随机选取一组参数,然后运行我的算法——但我希望能够将该组参数保存到一个文件中,而不会被另一组参数覆盖,这样我就可以始终知道哪些参数导致了哪些结果。你想让我发布一个更大的代码吗,例如在pastebin上?如果你不局限于数字,那么我只需执行
sha1(repr(排序(my_dict.items())))
(灵感来源)。否则,请看@Wombatz的评论。问题,为什么字典的顺序很重要?-1-@tyteen4a03:我知道:我只是想举个例子。@tyteen4a03:我已将答案改为使用sha256。谢谢你,我可能会接受你的答案,并依靠运气。快速提问,如果我要使用“规范表示法”(我不知道这个词),我应该开始寻找什么?因此,这将是一个不同的问题,但作为一个可能非常接近的例子来看一下
import hashlib

def hash_item(m, k, v):
    m.update(k.encode('utf-8'))
    m.update(str(k).encode('utf-8'))

m = hashlib.sha256()
for k, v in values:
    hash_item(m, k, v)
print(m.digest())
# -> b'\xa5\xb42\xee\x03\x07\xbe\x7f\xa2:\xa0\x04a\xf5N\xee4\xba\x9dE%\x1bU\x04V}7\xa8\xda3\x9d\xff'