2016-01-23 58 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']] 
相关问题