2013-01-09 108 views
0

我正在使用Python 2.6.2。我有一個字典,它有元組(源,目的地)作爲它的值具有一定的權重的關鍵。複雜排序 - 多鍵

想對根據重量的降序排列源。在不同目的地的圖的元組中可能有多於一個相同的源。

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_dict其具有源作爲基於源作爲其值,密鑰和累計重量{源:重量}

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_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_sort中注意到相同源的鍵的順序並不重要,例如對於以5爲源的元組,((5,23),2)可以在((5,35),5)之前出現)或者在事件之後,儘管一方的價值低於另一方。

現在,這是我的挑戰,我正努力從3天前解決,

重新定義source_dictsource_dict_angle與角度補充信息,{來源:{角度:重量}}

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的目的地等等的元組。

有中介詞典,relation_graph其具有相對於源目的地的位置信息,{源:{角度:目的地:值}}

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_sort所做的解決方案,但效果不佳。感覺我必須以不同的方式去做。

是否有任何方法可以使用與graph_sort相同的方法?

欣賞,如果你能給我一些指點。

到現在爲止還會繼續工作。

補充說明2013年1月9日下午九時30分:梅里Regebro

我想的(元組)的基礎上,從source_dict_angle降值按鍵排序。

由(來源,目標)組成,但source_dict_angle只有來源和角度信息{來源:{角度:權重}}。它沒有目的地信息。我們無法像第一個例子中那樣對中的元組進行排序。

給出(未計算)relation_graph,其中我們有源,角度和目的地信息{來源:{angle:destination:value}}。我們將使用這個字典來查看哪個源與哪個目的地使用哪個角度(0度,90度,180度或270度)。

因此,我們將

  1. 首先是指source_dict_angle知道這是最高值。 在該給定示例中,源4與角180度具有即21

  2. 我們從relation_graph比較源4的所有目的地與角180的最高值,即[0,33,44,14,15,17, 21,41,27,30,31],如果它存在於。如果是,我們將(源,目標)元組排列在第一位,即(4,17)。這也可以用另一種方式完成,因爲我們必須對來源4進行排序,我們檢查來源4中的任何一個目的地是否存在於源4的角度180中relation_graph。如果是,我們將(源,目標)元組排在第一位。由於同一個源可以使用相同的角度與多個目標進行配對,因此我們有可能擁有多個(源,目標)元組。例如(4,17),(4,44)和(4,30)。這意味着,源4使用角度180連接到目的地17,目的地44和目的地30,因此是3對元組。這3對元組之間的順序不成問題。

  3. 一旦完成了這一步,我們將轉到source_dict_angle中的下一個最高值,執行上述步驟,直到所有源按降序排序。

+0

您是否知道'key'不必返回標量,但可以返回任何可比對象?例如,在你的情況下,它將有意義的返回元組作爲第一項,最重要的屬性(源),不太重要(重量)作爲第二項等等。 – patrys

+0

@patrys我不知道。 http://docs.python.org/2/library/functions.html#sorted的解釋看起來很簡短。我搜索瞭解你所指出的內容。我從下面Lennart Regebro的例子中看到,他已經顯示了調用函數的關鍵。這對我來說是新的,現在閱讀更多內容並查看示例。謝謝 –

回答

2

跳過中間字典,這不是必需的。

對於源上的排序,你只是做:

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) 

更新:

你需要停止使用的不同負載字典來保存所有屬於一起的不同數據。爲保存所有信息的項目創建一個類。

從我可以從你的問題中收集你有一個圖形項目的字典,保持來源,目的地和體重。然後,你又有另一本字典,保持懷疑。然後你有第三個字典保持角度。

相反只是這樣做:

class Graph(object): 
    def __init__(self, source, destination, weight, angle): 
     self.source = source 
     self.destination = destination 
     self.weight = weight 
     self.angle = angle 

你的排序問題是現在微不足道。

+0

對不起,如果我不清楚。我是初學者,需要花些時間閱讀和理解你的編碼。我基於source_dict的值進行排序,而不是關鍵,即源。中間字典不計算,但用於協助解決這個問題。我已經更新了我的作品以更好地解釋。請告知我是否可能誤解了你 –

+0

@SaravananK:你需要停止使用大量不同的字典來保存所有屬於不同的數據。爲保存所有信息的項目創建一個類。我已經更新了答案。 –

+0

@LennartRegebro,'Graph'看起來像一個候選人,成爲'collections.namedtuple'。 – patrys