将字典排序为列表并使新的排序字典在python中不起作用

时间:2014-05-31 17:22:09

标签: python sorting dictionary

我想在字典中输入值,所以我编写了一些代码,将它们分开,排序为列表,然后再放回另一个字典中。但是,我发现即使值已经排序,只要我将它放回字典中,它就会再次自行解析。我尝试了一个更简单的例子,同样的事情发生了,我相当肯定它可能是我忽略的东西,但不能弄明白这么一点帮助会不胜感激。

简易版

a = dict()
b = dict()

a['test3'] = 3
a['test2'] = 0
a['test5'] = 4

alist = a.keys()
alist.sort()

for i in range( len( alist ) ):
    b[alist[i]] = a[alist[i]]
    #result of alist[i] is test2, test3, test5 - b has values assigned in order this time

print b
#b is the exact same as a

我实际使用的版本(在问题位附近放了很多#)。对objValues变量进行了排序,但是一旦从edgeValues中拉出键,它们就会再次排序。
对于我正在做的事情的基本概念,我试图制作某种模块化的东西,你可以制作一个正方形(记住这是第一个版本),然后给出每个边缘都有一个名称,它将连接到其他类似的边缘,例如,您可能有一条河流在正方形或道路或建筑物之间流动。

当前的字典样式是这样的,因此我需要3级排序

edgename:{ objectname: [list of sides], objectname: [list of sides]...


def ph_getStoredInfo():
    #process stored values
    objValues = dict()

    #just so it will work with copy + paste
    allEdges = []
    allEdges.append ( [['test4'], ['pCube1', 'x'], ['pCube1', 'y'], ['pCube1', '-y'], ['pCube1', '-x'], ['pCube2', '-x']] )
    allEdges.append ( [['test2'], ['pCube2', '-x'], ['pCube2', 'x']] )
    allEdges.append ( [['test3'], ['pCube2', '-x'], ['pCube2', 'x']] )

    for i in range( len( allEdges ) ):
        edgeName = allEdges[i][0][0]
        objValues[edgeName] = dict()
        for j in range( len( allEdges[i] )-1 ):
            objInfo = allEdges[i][j+1]
            if objValues[edgeName].get(objInfo[0]) == None:
                objValues[edgeName][objInfo[0]] = [objInfo[1]]
            else:
                objValues[edgeName][objInfo[0]].append( objInfo[1] )
    #sort all values
    sortedList = dict()
    edgeValues = objValues.keys()
    edgeValues.sort()
    for i in range( len( edgeValues ) ):
        objNames = objValues[edgeValues[i]].keys()
        objNames.sort()
        sortedList[edgeValues[i]] = dict()
        for j in range( len( objNames ) ):
            objSides = objValues[edgeValues[i]][objNames[j]]
            objSides.sort()
            sortedList[edgeValues[i]][objNames[j]] = dict()
            for m in range( len( objSides ) ):
                if len( sortedList[edgeValues[i]][objNames[j]] ) == 0:
                    sortedList[edgeValues[i]][objNames[j]] = [objSides[m]]
                else:
                    sortedList[edgeValues[i]][objNames[j]].append( objSides[m] )
    return sortedList

#display text
objValues = ph_getStoredInfo()
#####################BIT THAT DOESN'T WORK######################
edgeValues = objValues.keys()
################################################################
for i in range( len( edgeValues ) ):
    objNames = objValues[edgeValues[i]].keys()
    outputText = "Edge '" + str( edgeValues[i] ) + "' is applied to '"
    for j in range( len( objNames ) ):
        outputText += objNames[j] + "' for side"
        objSides = objValues[edgeValues[i]][objNames[j]]
        if len( objSides ) > 1:
            outputText += "s"
        for m in range( len( objSides ) ):
            outputText += " " + objSides[m]
            if m == len( objSides )-2:
                outputText += " and"
            if m < len( objSides )-2:
                outputText += ","
        if j == len( objNames )-2:
            outputText += " and '"
        if j < len( objNames )-2:
            outputText += ", '"
    print outputText

2 个答案:

答案 0 :(得分:2)

Dictionaries在Python中是无序的。

引用文档:

  

最好将字典视为无序键组:值   对,要求密钥是唯一的(在一个内   字典)。

警告:许多新的Pythonistas坐下来试验并发现,对于一些插入/删除使用整数键,dict似乎维持其顺序:

>>> d={1:1, 2:2, 3:3, 4:4}
>>> d
{1: 1, 2: 2, 3: 3, 4: 4}
>>> d[2]=20
>>> d
{1: 1, 2: 20, 3: 3, 4: 4}
>>> del d[2]
>>> d
{1: 1, 3: 3, 4: 4}
>>> d[20]=2
>>> d
{1: 1, 3: 3, 4: 4, 20: 2}

首先,这是某些版本上不可预测的实现工件。其次,它并不总是成立:

>>> for i in range(0,6): d[10**i] = 'power of ten'
... 
>>> d
{100000: 'power of ten', 1: 'power of ten', 100: 'power of ten', 1000: 'power of ten', 10: 'power of ten', 10000: 'power of ten'}

所以不要犯这个错误。

您可以使用dict子类OrderedDict来维护插入顺序,从而以您想要的顺序存储无序字典:

from collections import OrderedDict

a = dict()
b = OrderedDict()

a['test3'] = 3
a['test2'] = 0
a['test5'] = 4

for k, v in sorted(a.items(), key=lambda t: t[1]):
    b[k]=v

print a
# {'test3': 3, 'test2': 0, 'test5': 4} 
print b
# OrderedDict([('test2', 0), ('test3', 3), ('test5', 4)])

知道OrderedDict只保留插入顺序。它不会为新插入的键值保留某种形式的排序顺序。唯一的顺序是新密钥,值保证在dict的末尾。

答案 1 :(得分:0)

字典中键的顺序以Python本身定义的顺序返回。在你的简单例子中,你很幸运。

所以,我想简短的回答是你不允许存储已排序的字典键。

也许您可以单独保存列表中的排序键,并使用它来枚举您的词典。