如何在Python中对单个元素中具有不同字符优先级的嵌套列表进行排序?
很抱歉没能写出一个好标题 我有一份清单:如何在Python中对单个元素中具有不同字符优先级的嵌套列表进行排序?,python,list,sorting,nested-lists,Python,List,Sorting,Nested Lists,很抱歉没能写出一个好标题 我有一份清单: some_list = [[X, '4x01'], [X, '3x02'], [X, '4x02'], [X, '3x01']] 其中X是我不在乎的东西 我想按照以下优先级对列表中的第二个元素进行排序: 按降序排列的第一个字符 最后2个字符按升序排列 最终输出应为: some_list = [[X, '4x01'], [X, '4x02'], [X, '3x01'], [X, '3x02']] 注意:给出错误答案的解决方案是: output = so
some_list = [[X, '4x01'], [X, '3x02'], [X, '4x02'], [X, '3x01']]
其中X
是我不在乎的东西
我想按照以下优先级对列表中的第二个元素进行排序:
some_list = [[X, '4x01'], [X, '4x02'], [X, '3x01'], [X, '3x02']]
注意:给出错误答案的解决方案是:
output = sorted(some_list, key=lambda lis: lis[3], reverse=True)
示例运行(将X定义为None
以便我可以复制粘贴列表定义):
在这种情况下,您可以像@Amber那样使用复合键。然而,这种方法并不总是有效的:例如,如果两个组件都有两个字符长,它就会失败(因为
-ord(x[1][0])
技巧不再有效)
以下是一个更通用的解决方案:
In [15]: X = None
In [16]: some_list = [[X, '4x01'], [X, '3x02'], [X, '4x02'], [X, '3x01']]
In [17]: l = sorted(some_list, key=lambda (x,y):y[-2:])
In [18]: l = sorted(l, key=lambda (x,y):y[:1], reverse=True)
In [19]: l
Out[19]: [[None, '4x01'], [None, '4x02'], [None, '3x01'], [None, '3x02']]
它一次按一个标准对列表进行排序,并利用Python的排序是不正确的这一事实
更一般的方法是提供一个比较标准:
def f((x1,y1), (x2,y2)):
c = cmp(y1[:1], y2[:1])
if c != 0: return -c
return cmp(y1[-2:], y2[-2:])
这可以按如下方式使用:
In [39]: sorted(some_list, cmp=f)
Out[39]: [[None, '4x01'], [None, '4x02'], [None, '3x01'], [None, '3x02']]
这是正确的。尽管思考了几个小时,我永远也不会得出这个答案。谢谢Spython一行非常好。您可以做很多事情,但仍然可以-与Perl相比,它们仍然是可读的。如果您做到这一点,更好的选择可能是只编写一个比较函数。这将避免您必须对列表进行两次排序(如果列表很大,这可能是一项昂贵的操作)。@Amber:Fair point。不过,这是一个值得了解的有用技巧。请帮助我理解你的论点。如果是两个字符长的话,
-ord(x[1][:1])
会不会改成这样呢?@elwc:我想你的意思是-ord(x[1][:2])
。这将引发异常,因为ord()
只能应用于单个字符串。-ord(…)
技巧依赖于..
正好是一个字符长。你的假设很好。难怪我没有出错。关于刚才提到的比较函数@Amber,那是什么?
def f((x1,y1), (x2,y2)):
c = cmp(y1[:1], y2[:1])
if c != 0: return -c
return cmp(y1[-2:], y2[-2:])
In [39]: sorted(some_list, cmp=f)
Out[39]: [[None, '4x01'], [None, '4x02'], [None, '3x01'], [None, '3x02']]