Python:按不同顺序按多列对字符串和数字的嵌套列表进行排序
给定一个嵌套列表,如Python:按不同顺序按多列对字符串和数字的嵌套列表进行排序,python,python-3.x,list,sorting,Python,Python 3.x,List,Sorting,给定一个嵌套列表,如 a=[“a”、“z”]、[“b”、“y”]、[“c”、“x”]、[“d”、“x”]、[“e”、“x”]] #应该输出 a=['e','x'],['d','x'],['c','x'],['b','y'],['a','z']] 如果只有一个排序出现重复,我将如何按第二列升序排序,然后按第一列降序排序 我基本上是在尝试实现SQL的col1 ASC排序、col2 DESC排序、col3 ASC排序 我可以做类似的事情 sorted(sorted(a,key=lambda x:(x
a=[“a”、“z”]、[“b”、“y”]、[“c”、“x”]、[“d”、“x”]、[“e”、“x”]]
#应该输出
a=['e','x'],['d','x'],['c','x'],['b','y'],['a','z']]
如果只有一个排序出现重复,我将如何按第二列升序排序,然后按第一列降序排序
我基本上是在尝试实现SQL的col1 ASC排序、col2 DESC排序、col3 ASC排序
我可以做类似的事情
sorted(sorted(a,key=lambda x:(x[1])),key=lambda x:(x[0]),reverse=True)
但我想知道是否有更好更简单的方法来实现这一点。您可以在lambda的返回值中指定这两个条件
>>> a = [["a", "z"], ["b", "y"], ["c", "x"], ["d", "x"], ["e", "x"]]
>>> sorted(a, key = lambda x: (x[1], -1 * ord(x[0])))
[['e', 'x'], ['d', 'x'], ['c', 'x'], ['b', 'y'], ['a', 'z']]
>>>
要将该行为扩展到常规键,请定义自己的函数来计算键的值并在lambda中提供这些值。请参见下文。这些功能可以是简单的,也可以是复杂的。
可以认为它们类似于为快速排序库提供的压缩函数,但不是-1、+1,0,而是为Python将用于排序的键返回一个绝对值
>>> def first_key(x):
... return x
...
>>> def second_key(x):
... return -1 * ord(x)
...
>>> sorted(a, key = lambda x: (first_key(x[1]), second_key(x[0])))
[['e', 'x'], ['d', 'x'], ['c', 'x'], ['b', 'y'], ['a', 'z']]
>>> a
[['a', 'z'], ['b', 'y'], ['c', 'x'], ['d', 'x'], ['e', 'x']]
>>>
你可以用
sorted(a, key=lambda x: (x[1], [-ord(x) for x in x[0]]))
这可以在任意长度的字符串上一次执行。其思想是使用
x
中每个字符的序数值作为键
比较器中的第二个元素。一元-
反转值,给出所需的反向顺序。排序(a,key=lambda x:[x[1],-ord(x)表示x中的x[0]])
使用x
中每个字符的顺序值一次性工作,但这有点难看,列表理解速度似乎较慢。如果有一个字符串的可比值可以输入x[0]
,那就更好了。@ggorlen会将第一列解释为十六进制数来替代列表吗sorted(a,key=lambda x:[x[1],-int(x[0].encode('utf-8').hex())])
@Kevin有趣的想法,谢谢。这似乎是可行的,但问题是,如果字符串真的很长,int
调用会创建一个很大的数字,可能在内部看起来像一个数组,所以我不确定这是否是一个改进。代码实际上也不再可读了。我仍然希望有一个库函数调用可以使字符串具有可比性,但这可能不存在。它不处理多字符字符串。我在评论中的解决方案似乎更安全、更可靠。如果你愿意,你可以用它。几乎可以肯定,这些单字符字符串是更真实字符串的占位符<代码>-ord(x[0])比-1*ord(x[0]更干净)
.ggorlen是正确的,因为我确实打算在更长的字符串上使用它,但是使用单独的函数为键提供更正确的答案可以解决这个问题。我认为使用元组而不是列表作为键在这里是首选的,因为它具有不变性?通常是的,但这并不重要,因为我们会立即将列表返回到库中,所以我们不可能在lambda中对其进行任何变异。尽管如此,还是更新了!我懂了。但我相信元组的构造时间会更快,因为它不会过度分配。但这种优化可能也可以忽略不计。你必须对其进行分析/基准测试,但这似乎是虚假的。