什么是用多种属性对列表进行排序的pythonic方法,例如,第一种排序是反向排序,但第二种排序不是?
给出一个列表什么是用多种属性对列表进行排序的pythonic方法,例如,第一种排序是反向排序,但第二种排序不是?
[ ['a','b'], ['x','y'], ['a','y'], ['x', 'b'] ]
我如何的方式,第一个元素是递减排序,但第二个元素进行排序,当越来越多的第一个元素等于排序呢?这个列表中的字符串可以任意长。
排序列表应该是
[ ['x', 'b'], ['x', 'y'], ['a', 'b'], ['a', 'y'] ]
我在考虑使用的sorted
一个单一的电话,但做起来的关键,以反映这种似乎不工作。
可以两次对其进行排序(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']]
似乎在一般情况下调用'sorted'两次是不可避免的。 – xuhdev
好,
我想在第一时间的方式是:
l.sort(key=lambda e: (255 - ord(e[0]), e[1]))
但是,这种方式元素必须是一个元组(我明白这是事实),每个元组的第一个元素必须是字符串/字符。
更好的解决方案可以从这里演变而来。
255是什么? – jolvi
真的没什么。我刚刚做出了一个快速和肮脏的草案 - 这个想法是保持0到255之间的范围,字符范围,但没有必要。 –
在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']]
的Javastic的方法是创建一个自定义的“Comparator”来实现您想要的自定义排序规则......然后传递自定义ru到Arrays.sort()方法。在Java 8中,这可以通过lambda,匿名类实例或具体类实例来完成。 Python会有类似的东西。 – scottb