Python 如何对散列对象进行排序

Python 如何对散列对象进行排序,python,Python,我需要对字典的键进行排序,以确保列表始终具有相同的顺序。我不管那是什么命令。但我需要秩序的一致性。这导致人们在使用我编写的软件包时遇到困难,因为他们希望设置一个随机种子并获得一致的测试结果,但即使他们设置了一个键,字典返回其值的顺序也会改变,这最终会影响随机化 我想做一些类似于排序(D.keys())的事情。但是,原则上,键可能不可排序。我无法控制那些钥匙是什么 我知道python的最新版本已经解决了这个问题,但我不想将使用限制在3.7 详情如下: 由于人们认为这是一个糟糕的问题,这里有更多的

我需要对字典的键进行排序,以确保列表始终具有相同的顺序。我不管那是什么命令。但我需要秩序的一致性。这导致人们在使用我编写的软件包时遇到困难,因为他们希望设置一个随机种子并获得一致的测试结果,但即使他们设置了一个键,字典返回其值的顺序也会改变,这最终会影响随机化

我想做一些类似于排序(D.keys())的事情。但是,原则上,键可能不可排序。我无法控制那些钥匙是什么

我知道python的最新版本已经解决了这个问题,但我不想将使用限制在3.7

详情如下:


由于人们认为这是一个糟糕的问题,这里有更多的细节(或者查看我提供的原始链接了解更多细节):

我写了一个算法来做随机流行病模拟。出于再现性的目的,人们希望指定一个种子,并让它在任何机器上运行并产生相同的结果。该算法使用networkx图(基于字典结构构建)

作为步骤的一部分,它需要从图形的边缘执行加权选择。这需要我将边放入列表中。如果列表的顺序不同,则无论是否使用同一种子,都会产生不同的结果


因此,我必须找到一种方法,使边列表在任何机器上保持一致的顺序。

如果您只想保持顺序,一种可能是插入顺序和对列表。如果与
OrderedDict
结合使用,将保留顺序并具有字典功能

>>> import collections
>>> d = collections.OrderedDict([(1,'a'),(3,'2')])
>>> d.keys()
odict_keys([1, 3])

所以如果我理解正确。。。任务是在不保留插入顺序的旧版本Python上,从普通的dict中一致地选择相同的随机键,同时对键类型一无所知,也不显式地设置哈希种子。我认为这在一般情况下是不可能的,因为对象“同一性”的整个概念甚至不存在这样的限制性假设

唯一想到的是以某种方式序列化键,并对其序列化形式进行排序<代码>pickle.dump应该适用于大多数键类型(尽管并非所有键都可以被pickle)。但是如果键类型允许排序,那么简单地使用它可能会更健壮

导入pickle
尝试:
已排序的键=已排序(我的目录)
除类型错误外:
已排序的密钥=已排序的(我的dict,密钥=lambda x:pickle.dumps(x,协议=3))
不过,有一些警告:

  • 不同Python版本的pickle表示形式不同(请参阅)。这就是为什么我在上面的例子中设置
    protocol=3
    ;这对于Python3.0和更新版本应该是一样的,尽管它不支持像Protocol4那样多的对象类型

  • 对象可以定义自己的酸洗,因此不能保证它是可复制的。特别是

  • 字典的pickle表示仍然依赖于字典的顺序,这取决于Python版本和哈希种子。对象也是如此,因为默认情况下,这些对象是通过调用其
    \uuu dict\uu
    方法进行pickle处理的

    如果您想变得非常棘手,也许您可以创建一个自定义的
    Pickler
    ,在pickle字典之前对字典进行排序(使用
    OrderedDict
    实现跨Python版本的可移植性)。。。但最终,这并不能解决全部问题


如果词典的一致顺序很重要,那么它可能应该是一个
有序的dict
?为什么词典的排序目前会引起问题?这些困难是什么?为什么包的用户依赖词典排序来获得测试结果?像
{1:'a',2:'b'}=={2:'b',1:'a'}
这样的字典等式应该在所有情况下都适用。@jornsharpe-我不能使用
OrderedDict
,因为它实际上来自networkx图形。我可以要求用户输入OrderedGraph,但我不希望这样做,因为这需要额外的复杂程度,我认为这不适合这个问题。@Thomas-算法需要从字典中随机选择元素(大致上,比这更细微一点),但选择哪一个取决于python提供的顺序,并且将独立于用户选择的种子而有所不同。也有,但同样不能保证一致的顺序。我不能将其设置为有序的dict。它来自networkx图形(使用dict作为其基础结构),用户将预定义它。@Joel不幸的是,在这种情况下,如果您无法隐藏您正在使用dict,您将被卡住。根据定义,口述并不保证任何秩序。这就是它获得O(1)选择、插入和删除的方式。是的,我知道这一点。但是,假设所有的键都是字符串,我仍然可以对键进行排序。我正在寻找一种方法,即使对象本身没有定义的关系,也能一致地对可散列对象进行排序。