2013-10-04 68 views
0

下面的列表具有格式(ID,等級值):Python的高級列表排序

[(A, 1, None), 
(B, 1, None), 
(C, 1, None), 
(A, 2, 1.1), 
(B, 2, 5.0), 
(C, 2, 5.0), 
(C, 3, 40), 
(B, 3, 55)] 

所以美中不足的是根據自己的價值觀與同相同水平的項目進行排序從一個級別降低。如果下面的值級別是相等的,則它低於2級,依此類推。所以最終列表應該看起來像這樣:

[(A, 1, None), 
(C, 1, None), <- this moved up because @ lvl3 C['value'] < B['value'] 
(B, 1, None), 
(A, 2, 1.1), 
(C, 2, 5.0), <- this moved up because @ lvl3 C['value'] < B['value'] 
(B, 2, 5.0), 
(C, 3, 40), 
(B, 3, 55),] 

有人可以建議一個算法來實現它嗎?順便說一句,我總是通過然後排序的首發名單由水平

+0

寫some_list.sort(your_method)您的自定義比較法 –

+0

我已經更新了我的問題。 A位於頂端,因爲在2級A ['level'] and3p

+0

已更新我的問題 – and3p

回答

5

你需要一個查找表,每(ID, level)元組確定的值。你需要的所有可能的層次查找添加到排序關鍵字:

# Lookup for values by (id, level) 
values = {} 
minlevel, maxlevel = float('inf'), float('-inf') 
for id_, level, value in inputlist: 
    values[id_, level] = value 
    if level < minlevel: 
     minlevel = level 
    if level > maxlevel: 
     maxlevel = level 

def level_sort(tup): 
    id_, level, value = tup 
    sortkey = [level] 
    for l in range(minlevel, maxlevel + 1): 
     sortkey.append(values.get((id_, l)) if l >= level else None) 
    return sortkey 

sorted(inputlist, key=level_sort) 

排序函數生成值的列表進行排序,從自己的水平的值(None填充任何下級)加上更高級別的相同ID的值。

例如,對於(B, 1, None)(C, 1, None)元組,分類功能輸出:

>>> level_sort(('B', 1, None)) 
[1, None, 5.0, 55] 
>>> level_sort(('C', 1, None)) 
[1, None, 5.0, 40] 

其中只有最後一個值不同,並確定最終的排序順序。

爲此,您需要首先了解輸入列表中的最小和最大級別,因此需要更詳細的地圖構建循環。

演示:

>>> from pprint import pprint 
>>> A, B, C = 'ABC' 
>>> inputlist = [(A, 1, None), 
... (B, 1, None), 
... (C, 1, None), 
... (A, 2, 1.1), 
... (B, 2, 5.0), 
... (C, 2, 5.0), 
... (C, 3, 40), 
... (B, 3, 55)] 
>>> values = {} 
>>> minlevel, maxlevel = float('inf'), float('-inf') 
>>> for id_, level, value in inputlist: 
...  values[id_, level] = value 
...  if level < minlevel: 
...   minlevel = level 
...  if level > maxlevel: 
...   maxlevel = level 
... 
>>> def level_sort(tup): 
...  id_, level, value = tup 
...  sortkey = [level] 
...  for l in range(minlevel, maxlevel + 1): 
...   sortkey.append(values.get((id_, l)) if l >= level else None) 
...  return sortkey 
... 
>>> pprint(sorted(inputlist, key=level_sort)) 
[('A', 1, None), 
('C', 1, None), 
('B', 1, None), 
('A', 2, 1.1), 
('C', 2, 5.0), 
('B', 2, 5.0), 
('C', 3, 40), 
('B', 3, 55)] 
+0

這工作就像一個魅力。非常感謝! – and3p