2016-06-22 107 views
2

我想基於多個鍵對元組列表進行排序。例如,我有元組名單:如何基於列表中的鍵排序元組列表?

list_t = [(1, 3, 5, 6, 9, 10), (1, 2, 3, 4, 5, 61), (1, 2, 3, 0, 9, 81), (1, 2, 6, 7, 9, 54), (1, 3, 5, 6, 12, 43)] 

有一次,我想第一,第二,第三和第五的元組的元素對它進行排序:

keys = [0, 1, 2, 4] 
list_t_sorted = [(1, 2, 3, 4, 5, 61), (1, 2, 3, 0, 9, 81), (1, 2, 6, 7, 9, 54), (1, 3, 5, 6, 9, 10), (1, 3, 5, 6, 12, 43)] 

另一次我只需要通過元組的第三個元素對它進行排序:

keys = [2] 
list_t_sorted = [(1, 2, 3, 4, 5, 61), (1, 2, 3, 0, 9, 81), (1, 3, 5, 6, 9, 10), (1, 3, 5, 6, 12, 43), (1, 2, 6, 7, 9, 54)] 

到目前爲止,我嘗試這種代碼,但它不會返回預期的結果:

def sort_list(keys, list_t): 
    return sorted(list_t, key=lambda l: (l[x] for x in keys)) 

例如,對於keys = [0,1,2,4],它返回[(1,3,5,6,9,10),(1,2,3,4,5,61) ,(1,3,5,6,12,43),(1,2,6,7,9,54),(1,2,3,0,9,81)]中,不基於鍵。

任何人都可以幫助我嗎?謝謝!

+0

你說這不返回預期的結果。什麼_does_它返回? – Delioth

+0

基於密鑰的元組沒有排序的列表。例如,對於keys = [0,1,2,4],它返回[(1,3,5,6,9,10),(1,2,3,4,5,61),(1, (1,2,3,6,6,12,43),(1,2,6,7,9,54),(1,2,3,0,9,81)],其不在鍵上排序! – Malgi

回答

6

你在這裏。你可以閱讀更多關於operator.itemgetterhere in the docs

import operator 
list_t = [(1, 3, 5, 6, 9, 10), (1, 2, 3, 4, 5, 61), (1, 2, 3, 0, 9, 81), (1, 2, 6, 7, 9, 54), (1, 3, 5, 6, 12, 43)] 
keys = [0, 1, 2, 4] 
sorted(list_t, key=operator.itemgetter(*keys)) 

輸出:

[(1, 2, 3, 4, 5, 61), 
(1, 2, 3, 0, 9, 81), 
(1, 2, 6, 7, 9, 54), 
(1, 3, 5, 6, 9, 10), 
(1, 3, 5, 6, 12, 43)] 
+0

非常感謝您的快速回答! – Malgi

2

michael_j_ward的回答是更清潔的解決你的問題,但如果你想知道什麼地方錯了你最初的想法:

您正在嘗試進行排序生成器對象,我猜測它有不同的等同方式。表明這一點的方法是通過展示你實際上是試圖用一個排序的循環:

>>> def sort_list(keys, list_t): 
...  for l in list_t: 
...    print (l[x] for x in keys) 
...  return sorted(list_t, key = lambda l: (l[x] for x in keys)) 
... 
>>> sort_list(keys, list_t) 
<generator object <genexpr> at 0x105bc1af0> 
<generator object <genexpr> at 0x105bc1af0> 
<generator object <genexpr> at 0x105bc1af0> 
<generator object <genexpr> at 0x105bc1af0> 
<generator object <genexpr> at 0x105bc1af0> 
[(1, 3, 5, 6, 12, 43), (1, 2, 6, 7, 9, 54), (1, 2, 3, 0, 9, 81), (1, 2, 3, 4, 5, 61), (1, 3, 5, 6, 9, 10)] 

這顯然不是你想要的輸出,並具有與發電機是如何被比較的事。如果你想與你原來的想法(沒有itemgetter)做到這一點,明確創建tuples代替發電機:

>>> def sort_list(keys, list_t): 
...  return sorted(list_t, key = lambda l: tuple(l[x] for x in keys)) 
... 
>>> sort_list(keys, list_t) 
[(1, 2, 3, 4, 5, 61), (1, 2, 3, 0, 9, 81), (1, 2, 6, 7, 9, 54), (1, 3, 5, 6, 9, 10), (1, 3, 5, 6, 12, 43)] 
+0

感謝您的精彩解說! – Malgi