2016-06-08 79 views
3

我想知道用兩個鍵對一列元組進行排序的Pythonic方法,用一個(且只有一個)鍵進行排序的順序是相反的,與另一個排序將不區分大小寫。 更具體而言,我有一個包含像元組的列表:用兩個鍵排序Python列表,但只有一個按相反順序

myList = [(ele1A, ele2A),(ele1B, ele2B),(ele1C, ele2C)] 

我可以使用下面的代碼以將其與兩個鍵進行排序:

sortedList = sorted(myList, key = lambda y: (y[0].lower(), y[1])) 

排序以相反的順序,我可以使用

sortedList = sorted(myList, key = lambda y: (y[0].lower(), y[1]), reverse = True) 

但這會按照與兩個鍵相反的順序排序。

任何提示非常感謝。

回答

3

兩個鍵的時候,我們需要理清兩個制約因素之一升序和其他在同一列表或任何
在您的例子降列表
sortedList = sorted(myList, key = lambda y: (y[0].lower(), y[1]))只能在一個訂單
排序整個名單將被用來你可以嘗試這些檢查發生了什麼

sortedList = sorted(myList, key = lambda y: (y[0].lower(), -y[1])) 
sortedList = sorted(myList, key = lambda y: (-y[0].lower(), y[1])) 
sortedList = sorted(myList, key = lambda y: (-y[0].lower(), -y[1])) 

希望在這之後你會明白;)

+0

非常簡潔,非常感謝! –

1

有時,替代一點,但使用比較功能。 sorted從其介紹到2.4有一個cmp參數,但它從Python 3中刪除,轉而使用更高效的key函數。在3.2中,cmp_to_key被添加到functools;它通過將原始對象封裝在一個對象中創建鍵,該對象的比較函數基於cmp函數。(你可以看到cmp_to_keyend of the Sorting How-To

一個簡單的定義,根據你的情況,因爲較低的外殼是比較昂貴的,你可能想要做一個組合:

class case_insensitive_and_2nd_reversed: 
    def __init__(self, obj, *args): 
     self.first = obj[0].lower() 
     self.second = obj[1] 
    def __lt__(self, other): 
     return self.first < other.first or self.first == other.first and other.second < self.second 
    def __lt__(self, other): 
     return self.first < other.first or self.first == other.first and other.second < self.second 
    def __gt__(self, other): 
     return self.first > other.first or self.first == other.first and other.second > self.second 
    def __le__(self, other): 
     return self.first < other.first or self.first == other.first and other.second <= self.second 
    def __ge__(self, other): 
     return self.first > other.first or self.first == other.first and other.second >= self.second 
    def __eq__(self, other): 
     return self.first == other.first and self.second == other.second 
    def __ne__(self, other): 
     return self.first != other.first and self.second != other.second 

sortedList = sorted(myList, key = case_insensitive_and_2nd_reversed) 
0

方法1

一簡單的解決方案,但可能不是最有效的是分類兩次:第一次使用第二個元素,第二個使用第一個元素:

sortedList = sorted(sorted(myList, key=lambda (a,b):b, reverse=True), key=lambda(a,b):a) 

或分解:

tempList = sorted(myList, key=lambda (a,b):b, reverse=True) 
sortedList = sorted(tempList, key=lambda(a,b):a)) 

方法2

如果你的元素是數字,你可以騙一點:

sorted(myList, key=lambda(a,b):(a,1.0/b)) 

方法3

另一種方法是交換元素比較元素時:

def compare_func(x, y): 
    tup1 = (x[0], y[1]) 
    tup2 = (x[1], y[0]) 
    if tup1 == tup2: 
     return 0 
    elif tup1 > tup2: 
     return 1 
    else: 
     return -1 

sortedList = sorted(myList, cmp=compare_func) 

或者,使用lambda來避免寫功能:

sortedList = sorted(
    myList, 
    cmd=lambda (a1, b1), (a2, b2): 0 if (a1, b2) == (a2, b1) else 1 if (a1, b2) > (a2, b1) else -1 
    ) 

我建議反對這種做法,因爲它是凌亂和cmd關鍵字不可用在Python 3