Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:按不同顺序按多列对字符串和数字的嵌套列表进行排序_Python_Python 3.x_List_Sorting - Fatal编程技术网

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中对其进行任何变异。尽管如此,还是更新了!我懂了。但我相信元组的构造时间会更快,因为它不会过度分配。但这种优化可能也可以忽略不计。你必须对其进行分析/基准测试,但这似乎是虚假的。