2016-01-23 109 views
1

給出一個列表什麼是用多種屬性對列表進行排序的pythonic方法,例如,第一種排序是反向排序,但第二種排序不是?

[ ['a','b'], ['x','y'], ['a','y'], ['x', 'b'] ] 

我如何的方式,第一個元素是遞減排序,但第二個元素進行排序,當越來越多的第一個元素等於排序呢?這個列表中的字符串可以任意長。

排序列表應該是

[ ['x', 'b'], ['x', 'y'], ['a', 'b'], ['a', 'y'] ] 

我在考慮使用的sorted一個單一的電話,但做起來的關鍵,以反映這種似乎不工作。

+0

的Javastic的方法是創建一個自定義的「Comparator」來實現您想要的自定義排序規則......然後傳遞自定義ru到Arrays.sort()方法。在Java 8中,這可以通過lambda,匿名類實例或具體類實例來完成。 Python會有類似的東西。 – scottb

回答

7

可以兩次對其進行排序(Python使用上已經排序的部分表現良好穩定排序):

>>> l = [ ['a','b'], ['x','y'], ['a','y'], ['x', 'b'] ] 
>>> sorted(sorted(l, key=lambda x: x[1]), key=lambda x: x[0], reverse=True) 
[['x', 'b'], ['x', 'y'], ['a', 'b'], ['a', 'y']] 

或者您可以使用ord()得到一個整數,否定它:

>>> l = [ ['a','b'], ['x','y'], ['a','y'], ['x', 'b'] ] 
>>> sorted(l, key=lambda x: (-ord(x[0]), x[1])) 
[['x', 'b'], ['x', 'y'], ['a', 'b'], ['a', 'y']] 
+0

似乎在一般情況下調用'sorted'兩次是不可避免的。 – xuhdev

1

好,

我想在第一時間的方式是:

l.sort(key=lambda e: (255 - ord(e[0]), e[1])) 

但是,這種方式元素必須是一個元組(我明白這是事實),每個元組的第一個元素必須是字符串/字符。

更好的解決方案可以從這裏演變而來。

+0

255是什麼? – jolvi

+0

真的沒什麼。我剛剛做出了一個快速和骯髒的草案 - 這個想法是保持0到255之間的範圍,字符範圍,但沒有必要。 –

1

在Python 2,你可以這樣做:

>>> l = [ ['a','b'], ['x','y'], ['a','y'], ['x', 'b'] ] 
>>> 
>>> sorted(l, lambda (a, b), (c, d): cmp(c, a) or cmp(b, d)) 
[['x', 'b'], ['x', 'y'], ['a', 'b'], ['a', 'y']] 

在Python 3同樣的事情是可能的,但醜:

>>> import functools 
>>> sorted(l, key=functools.cmp_to_key(lambda a, b: (a[0] < b[0]) - (a[0] > b[0]) or (a[1] > b[1]) - (a[1] < b[1]))) 
[['x', 'b'], ['x', 'y'], ['a', 'b'], ['a', 'y']] 

或者與助手:

>>> def cmp(a, b): 
    return (a > b) - (a < b) 

>>> sorted(l, key=functools.cmp_to_key(lambda a, b: cmp(b[0], a[0]) or cmp(a[1], b[1]))) 
[['x', 'b'], ['x', 'y'], ['a', 'b'], ['a', 'y']] 
相關問題