示例:
a =
[
[['test', 21, 28], ['test', 61, 68], ['test', 111, 118], ['test', 118, 125]],
[['Columns', 21, 28], ['Columns', 61, 68], ['Columns', 111, 118], ['Columns', 118, 125], ['Columns', 128, 135]],
[['Delete', 14, 20], ['Delete', 47, 53], ['Delete', 54, 60], ['Delete', 78, 84], ['Delete', 95, 101]],
[['rw', 21, 28], ['rw', 61, 68], ['rw', 111, 118]]
]
我想要做的是按照子列表的反转长度对嵌套列表进行排序 但如果子列表的长度相同,则保持原始顺序。
预期结果:
[
[['Columns', 21, 28], ['Columns', 61, 68], ['Columns', 111, 118], ['Columns', 118, 125], ['Columns', 128, 135]],
[['Delete', 14, 20], ['Delete', 47, 53], ['Delete', 54, 60], ['Delete', 78, 84], ['Delete', 95, 101]],
[['test', 21, 28], ['test', 61, 68], ['test', 111, 118], ['test', 118, 125]],
[['rw', 21, 28], ['rw', 61, 68], ['rw', 111, 118]]
]
我知道我可以使用它来按反向长度对列表进行排序,但它不会保留原始顺序:
a = sorted(a, key=len, reverse=True)
(它反转了子列表'删除'以及'列')
如何按照子列表的反向长度对列表进行排序并保留原始顺序?
答案 0 :(得分:4)
TimSort是一种稳定的排序,因此它通常会保留相同项目的顺序。所以你的代码应该正常工作。
或者,摆脱reverse=True
并使用返回子列表长度负数的键函数。
a = [
[['test', 21, 28], ['test', 61, 68], ['test', 111, 118], ['test', 118, 125]],
[['Columns', 21, 28], ['Columns', 61, 68], ['Columns', 111, 118], ['Columns', 118, 125], ['Columns', 128, 135]],
[['Delete', 14, 20], ['Delete', 47, 53], ['Delete', 54, 60], ['Delete', 78, 84], ['Delete', 95, 101]],
[['rw', 21, 28], ['rw', 61, 68], ['rw', 111, 118]]
]
a.sort(key=lambda x: -len(x))
for row in a:
print(row)
<强>输出强>
[['Columns', 21, 28], ['Columns', 61, 68], ['Columns', 111, 118], ['Columns', 118, 125], ['Columns', 128, 135]]
[['Delete', 14, 20], ['Delete', 47, 53], ['Delete', 54, 60], ['Delete', 78, 84], ['Delete', 95, 101]]
[['test', 21, 28], ['test', 61, 68], ['test', 111, 118], ['test', 118, 125]]
[['rw', 21, 28], ['rw', 61, 68], ['rw', 111, 118]]
如果我使用
a.sort(key=len, reverse=True)
我得到与上面相同的输出。如果你没有得到那个输出,那么非常奇怪的东西正在发生。请注意,此版本比上述版本更有效,因为它直接调用len
(在C中实现并且它执行快速属性查找以确定对象的长度),并且Python函数调用相对较慢,它们是def
函数或lambda
s。
顺便说一句,当你想要就地排序列表时,你应该总是调用它的.sort
方法。内置sorted
函数实际上会创建一个新列表,将原始数据复制到该列表,然后在其上调用.sort
,然后将新列表绑定到目标。因此,避免创建该副本并在原始列表上自行调用.sort
会更有效。