Python:根据子列表的属性对2D列表进行排序



我有一个2D列表:

ls = [
['-2,60233106656288100', '2', 'C'],
['-9,60233106656288100', '2', 'E'],
['-4,60233106656288100', '2', 'E'],
['-3,60233106656288100', '2', 'C'],
['-5,60233106656288100', '4', 'T'],
['-0,39019660724115224', '3', 'E'],
['-3,60233106656288100', '2', 'T'],
['-6,01086748514074000', '1', 'Q'],
['-5,02684650459461800', '0', 'X'],
['-1,25228509312138300', 'A', 'N'],
['-0,85517128843547330', '3', 'E'],
['1,837508975733196200', '3', '-', 'E'],
['1,850925075915637700', '5', '-', 'T'],
['1,826767133229081000', '4', '-', 'C'],
['1,845357865328532300', '3', '-', 'E'],
['0,636275318914609100', 'a', 'n', 'N']
]

我想先排序,较短的子列表排序根据第二列之后,根据第三列,以便保持列表排序根据第二列(第一行第二列0,1,然后五2等但2开关的地方,我第一次有两个E然后两个C T)。在那之后我想根据第四列排序子列表的时间越长。A所在的行应该是短链表的最后一行a所在的行应该是最后一行。因此输出应该如下所示:

[
['-5,02684650459461800', '0', 'X'],
['-6,01086748514074000', '1', 'Q'],
['-9,60233106656288100', '2', 'E'],
['-4,60233106656288100', '2', 'E'],
['-3,60233106656288100', '2', 'C'],
['-2,60233106656288100', '2', 'C'],
['-3,60233106656288100', '2', 'T'],
['-0,39019660724115224', '3', 'E'],
['-0,85517128843547330', '3', 'E'],
['-5,60233106656288100', '4', 'T'],
['-1,25228509312138300', 'A', 'N'],
['1,837508975733196200', '3', '-', 'E'],
['1,845357865328532300', '3', '-', 'E'],
['1,826767133229081000', '4', '-', 'C'],
['1,850925075915637700', '5', '-', 'T'],
['0,636275318914609100', 'a', 'n', 'N']
]

我知道我可以按照第二列排序:

ls.sort(key=lambda x:x[1])

但是这将整个列表排序并给出:

['-5,02684650459461800', '0', 'X']
['-6,01086748514074000', '1', 'Q']
['-2,60233106656288100', '2', 'C']
['-9,60233106656288100', '2', 'E']
['-4,60233106656288100', '2', 'E']
['-3,60233106656288100', '2', 'C']
['-3,60233106656288100', '2', 'T']
['-0,39019660724115224', '3', 'E']
['-0,85517128843547330', '3', 'E']
['1,837508975733196200', '3', '-', 'E']
['1,845357865328532300', '3', '-', 'E']
['-5,60233106656288100', '4', 'T']
['1,826767133229081000', '4', '-', 'C']
['1,850925075915637700', '5', '-', 'T']
['-1,25228509312138300', 'A', 'N']
['0,636275318914609100', 'a', 'n', 'N']

我如何实现排序,以便我可以选择列表的某个部分然后对其排序,然后根据其他列再次排序?

如果我理解正确的话,您是想对列表进行排序

  • 首先由子列表的len
  • 然后通过列表中的每个元素,除了第一个元素,在前面的元素都相等的情况下使用下一个元素作为断点

为此,您可以使用tuple作为搜索键,使用len和从第二个元素开始的子列表的切片(即索引1):

ls.sort(key=lambda x: (len(x), x[1:]))

请注意,这也将使用第四个元素之后的元素作为进一步的限制,这可能不是想要的。此外,这会创建所有子列表的临时(近似)副本,如果列表较长,这可能是禁止的,即使所有比较可能在第3或第4个元素之后决定。

或者,如果您只需要前4个,或10个,或任何数量的元素,您可以创建一个封闭切片并使用它进行比较:

ls.sort(key=lambda x: (len(x), x[1:4]))

由于越界片被计算为空列表,因此即使列表的元素少于开始索引或结束索引,也可以执行此操作。

如何:

ls.sort(key=lambda x: (l := len(x), x[1], '' if l < 4 else x[3]))

这将首先按子列表的长度排序,然后按第二列排序,最后按第四列排序,如果有的话(如果没有,选择'',这仍然会一直排序到顶部)。

最新更新