How to write Python sort key functions for descending values
最近版本的python从以前的cmp函数向
例如,我想用一组字符串连接断开器字段对一组对象从最新到最旧进行排序。所以我希望日期的顺序是相反的,但是字符串的顺序是自然的。使用比较函数,我可以将日期字段与字符串字段的比较颠倒过来。但有了键函数,我需要找到一些方法来反转日期或字符串。
使用数字很容易(虽然很难看),只需从某个数据中减去它们,但是我是否需要找到一个相似的日期黑客(从另一个日期中减去它们,然后比较时间差?)和字符串(…我不知道如何以一种独立于区域设置的方式颠倒它们的顺序)。
我知道
做这件事的最通用方式是简单地将每一个键分开。Python's exporting is always stable so it is safe to do this:
1 2 | sort(data, key=tiebreakerkey) sort(data, key=datekey, reverse=True) |
请(假设关键功能的相关定义)给出数据类型的下行链路日期和上行链路断裂。
注意,这是一种缓慢的方法,而不是单复合键函数的产生,因为你将完成两个完整的输出,所以如果你能产生一个复合键,它将更好,但分解为分离的输出给一系列灵活性:给每一个柱提供一个关键函数,你可以使它们与具体的组合。对任何个人的打击。
For a completely generic option:
ZZU1
而且为了完整起见,尽管我真的认为应该避免在可能的地方:
1 2 | from functools import cmp_to_key sort(data, key=cmp_to_key(your_old_comparison_function)) |
我认为你不应该回到
The slow-but-elegant way to do this is to create a value wrapper that has reversed ordering:
1 2 3 4 5 6 7 8 9 | from functools import total_ordering @total_ordering class ReversedOrder: def __init__(self, value): self.value = value def __eq__(self, other): return other.value == self.value def __lt__(self, other): return other.value < self.value |
如果你没有
1 2 3 4 5 6 7 | import operator class ReversedOrder: def __init__(self, value): self.value = value for x in ['__lt__', '__le__', '__eq__', '__ne__', '__ge__', '__gt__']: op = getattr(operator, x) setattr(ReversedOrder, x, lambda self, other, op=op: op(other.value, self.value)) |
我想码头是不完整的。我解读"基本上"这个词,是指仍然有理由使用CMP fn微软雅黑,这是其中的一个。因为它是一种"吸引人的伤害",所以被认为是一种"吸引人的伤害":人们会对它有引力,即使是爱德华1〔5〕也是一种更好的选择。
但你的案子比
两个字,一个键,另一个键。
这是稳定的,不改变原始列表的顺序,但必须。)
It does matter which order you do the sorts in,if you care about how equal elements get out.
一种方法是使用
你可以这样做,不仅仅是为了两个层次(E.G.EDOCX1[…]和EDOCX1[…]13]),而是为了任何层次的需要。
比如说,如果你有
1 2 3 4 5 6 7 | d = [[1, 2, datetime(2017,1,2)], [2, 2, datetime(2017,1,4)], [2, 3, datetime(2017,1,3)], [2, 3, datetime(2017,1,4)], [2, 3, datetime(2017,1,5)], [2, 4, datetime(2017,1,1)], [3, 1, datetime(2017,1,2)]] |
你可以设定你的电子邮件地址
1 | df = pd.DataFrame(d) |
和使用EDOCX1
1 2 3 4 5 6 7 8 9 10 11 | sorted_df = df.sort_values(by=[0,1,2], ascending=[True,False,False]) sorted_list = sorted_df.agg(list, 1).tolist() [[1, 2, Timestamp('2017-01-02 00:00:00')], [2, 4, Timestamp('2017-01-01 00:00:00')], [2, 3, Timestamp('2017-01-05 00:00:00')], [2, 3, Timestamp('2017-01-04 00:00:00')], [2, 3, Timestamp('2017-01-03 00:00:00')], [2, 2, Timestamp('2017-01-04 00:00:00')], [3, 1, Timestamp('2017-01-02 00:00:00')]] |
注意到第一个柱是从上到下的,第二个和第三个柱是从上到下的,这是由于设置EDOCX1>11。
对于字符串,您可以使用一些通用的Acknowledged Maximum Value(如2 ^ 16 or 2 ^ 32)和Use Chr(),Unicode(),ord()to do the Math,just like for Integers.
在我的作品中,我知道我和UTF8中的弦乐有关,他们的命令在0xff下面,所以我写:
1 2 3 4 5 6 7 8 | def string_inverse(s): inversed_string = '' max_char_val = 0xffff for c in s: inversed_string += unicode(max_char_val-ord(c)) return inversed_string result.sort(key=lambda x:(x[1], string_inverse(x[0])), reverse=True) |
X is of type:(string,int),so what I get is,to abuse the sql:
1 | select * from result order by x[1] desc, x[0] asc; |