2016-06-08 35 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

相关问题