Python 复杂排序-多键

Python 复杂排序-多键,python,Python,我正在使用Python 2.6.2。我有一个字典,graph,它以元组(源、目标)为键,以一定的权重作为值 要根据来源按权重降序排序图形。图的元组中可能有多个相同的源,但目标不同 graph= {(2, 18): 0, (5, 13): 2, (0, 10): 2, (0, 36): 1, (3, 14): 2, (5, 23): 2, (0, 24): 1, (4, 32): 7, (2, 29): 0, (3, 27): 2, (0, 33): 2, (5, 42): 2, (5, 11):

我正在使用Python 2.6.2。我有一个字典,
graph
,它以元组(源、目标)为键,以一定的权重作为值

要根据来源按权重降序排序
图形
。图的元组中可能有多个相同的源,但目标不同

graph= {(2, 18): 0, (5, 13): 2, (0, 10): 2, (0, 36): 1, (3, 14): 2, (5, 23): 2, (0, 24): 1, (4, 32): 7, (2, 29): 0, (3, 27): 2, (0, 33): 2, (5, 42): 2, (5, 11): 2, (5, 39): 3, (3, 9): 8, (0, 41): 4, (5, 16): 5, (4, 17): 7, (4, 44): 7, (0, 31): 2, (5, 35): 5, (4, 30): 7}
创建了一个中介字典,
source\u dict
,它以source作为键,并以基于source的累计权重作为其值,{source:weight}

source_dict={0: 12, 2: 0, 3: 12, 4: 28, 5: 21}
在完成如下排序功能后

source_desc_sort=sorted(source_dict.items(), key=lambda x: x[1], reverse=True)
sortkeys = dict((x[0], index) for index,x in enumerate(source_desc_sort))
graph_sort = sorted(graph.iteritems(), key=lambda x: sortkeys[x[0][0]])
我得到一个排序图,
graph\u sort
如下所示

graph_sort= [((4, 17), 7), ((4, 44), 7), ((4, 30), 7), ((4, 32), 7), ((5, 23), 2), ((5, 35), 5), ((5, 13), 2), ((5, 42), 2), ((5, 11), 2), ((5, 39), 3), ((5, 16), 5), ((0, 10), 2), ((0, 36), 1), ((0, 24), 1), ((0, 33), 2), ((0, 41), 4), ((0, 31), 2), ((3, 14), 2), ((3, 27), 2), ((3, 9), 8), ((2, 29), 0), ((2, 18), 0)]
如果您在
graph\u sort
中注意到,同一源的键顺序并不重要,例如,对于源为5的元组,((5,23),2)可以位于((5,35),5)之前或之后,尽管其中一个的值低于另一个

这是我两天前开始努力解决的挑战

已将
source_dict
重新定义为
source_dict_angle
,添加了角度信息,{source:{angle:weight}

source_dict_angle={0: {0: 2, 90: 4, 180: 6}, 2: {0: 0, 270: 0}, 3: {180: 4, 270: 8}, 4: {0: 7, 180: 21}, 5: {0: 6, 90: 10, 180: 2, 270: 3}}
我喜欢做的排序与上面相同,但基于源的角度。例如,源为4且目标为180度的元组必须首先开始,因为它具有最高值,即21。然后是元组,源为5,目标为90度,以此类推

有中间字典,
relationship\u graph
,其中包含目标相对于源的位置信息,{source:{angle:destination:value}

relation_graph={0: {0: {32: [1], 36: [1], 23: [1], 24: [1], 16: [1]}, 90: {3: [1], 41: [1], 44: [1]}, 180: {33: [1], 10: [1], 31: [1]}}, 1: {}, 2: {0: {18: [1]}, 270: {29: [1]}}, 3: {180: {27: [1], 14: [1], 31: [1]}, 270: {0: [1], 33: [1], 36: [1], 9: [1], 1: [1], 24: [1], 41: [1], 10: [1]}}, 4: {0: {32: [1], 18: [1], 23: [1]}, 180: {0: [1], 33: [1], 44: [1], 14: [1], 15: [1], 17: [1], 21: [1], 41: [1], 27: [1], 30: [1], 31: [1]}}, 5: {0: {42: [1], 11: [1], 23: [1]}, 90: {7: [1], 8: [1], 16: [1], 35: [1]}, 180: {0: [1], 13: [1], 14: [1], 44: [1]}, 270: {1: [1], 2: [1], 39: [1], 29: [1]}}} 
预期结果

graph_sort_angle= [((4, 17), 7), ((4, 44), 7), ((4, 30), 7), ((5, 35), 5), ((5, 16), 5), ((3, 9), 8), ...
我目前还无法找到解决方案,我正在尝试重用我为
graph\u sort
所做的解决方案,但效果不佳。我觉得我必须用不同的方式来做

是否有任何方法可以使用与我对
graph\u sort
相同的方法

如果你能给我一些建议,我将不胜感激

我们将继续努力,直到那时

补充说明2013年1月9日晚上9:30:Lennart Regebro

我想根据
source\u dict\u angle
中的降序值对
graph
(tuple)的键进行排序

graph
由(源、目标)组成,但
source\u dict\u angle
仅包含源和角度信息,{source:{angle:weight}。它没有目的地信息。我们将无法像在第一个示例中那样从
graph
对元组进行排序

我们得到(未计算)
关系图
,其中我们有源、角度和目的地信息,{source:{angle:destination:value}}。我们将使用此字典查看哪个源使用哪个角度(0度、90度、180度或270度)与哪个目标配对

所以我们会

  • 首先参考
    source\u dict\u angle
    了解哪个值最高。 在此给定示例中,角度为180度的光源4具有最高值,即21

  • 我们将源4的所有目的地与
    关系图中的180角进行比较,即[0,33,44,14,15,17,21,41,27,30,31],如果它存在于
    关系图中。如果是,我们将(源、目标)元组排在第一位,即(4,17)。这也可以通过另一种方式完成,因为我们必须对源4进行排序,我们检查
    图中源4的任何目的地是否存在于
    关系图中源4的180角处。如果是,我们将(源、目标)元组排在第一位。由于同一个源可以使用相同的角度与多个目的地配对,因此我们有可能拥有多个(源、目的地)元组。e、 g(4,17)、(4,44)和(4,30)。这意味着,源4使用角度180连接到目的地17、目的地44和目的地30,从而连接到3对元组。这3对元组之间的顺序不是问题

  • 完成上述步骤后,我们进入
    source\u dict\u angle
    中的下一个最高值,直到所有震源都按降序排序


  • 跳过中间字典,这是不必要的

    要对源进行排序,只需执行以下操作:

    graph_sort = sorted(graph.iteritems(), key=lambda x: x[0][0])
    
    要按角度进行排序,请执行以下操作:

    def angle(x):
       key, value = x
       source, destination = key
       return <insert angle calculation here>
    
    graph_sort = sorted(graph.iteritems(), key=angle)
    

    您的排序问题现在变得微不足道。

    您是否知道
    键不必返回标量,但可以返回任何可比较的对象?例如,在您的例子中,返回元组时,最重要的属性(源)作为第一项,不太重要的属性(权重)作为第二项,依此类推,这是有意义的。@patrys我不知道。当时的解释似乎很简单。我在谷歌上搜索,想了解更多关于你所指内容的信息。我从下面Lennart Regebro的例子中看到,他展示了调用函数的键。这对我来说是新的,现在阅读更多并查看示例。谢谢你,如果我不清楚的话。我是初学者,花了一些时间阅读和理解你的代码。我是根据source_dict的值而不是键(即source)进行排序的。中间字典不是计算出来的,而是用来帮助解决这个问题的。为了更好地解释,我更新了上面的文字。如果我可能会误解,请务必通知我you@SaravananK:您需要停止使用不同字典的加载来保留所有属于同一个字典的不同数据。为保留所有信息的项创建一个类。我已经更新了答案。@lennartreegebro,
    Graph
    看起来像是成为
    collections.namedtuple
    的候选人。
    class Graph(object):
        def __init__(self, source, destination, weight, angle):
            self.source = source
            self.destination = destination
            self.weight = weight
            self.angle = angle