首页 > 解决方案 > Python:如何跟踪列表的排序方式?

问题描述

l0给定一个可能包含重复的任意顺序的数字列表,如何l_s在跟踪排序方式的同时对其进行排序,以便以后可以复制原始数字()? l0l0_orderl_in_l0_order

重点是应用于另一个列表,l0_order以便检索根据 排序的列表。ll_sl_in_l0_orderl0

到目前为止我使用的是

l0 = [1, 7, 3, 12, 12, 4]
ls = sorted(l0)
# ls
# [1, 3, 4, 7, 12, 12]

l0_order = [ls.index(v) for v in l0]
l_in_l0_order = [ls[i] for i in l0_order]
# l_in_l0_order
# [1, 7, 3, 12, 12, 4]

注意:对于具有相同值但不同的元素的列表id,上述方法可能会产生无效结果,因为index(afaik) 比较的是值,而不是 id。我不需要这种行为(的顺序id),但它可能与一般解决方案相关。

标签: pythonlistsorting

解决方案


如果您有l0相同但不相同的项目,您的系统将失败。此外,.index在每个成员上使用 是不必要的膨胀,O(N^2)。在这种情况下,您希望对进行排序,然后查找元素,而不是像以前那样对元素进行排序并查找键。一方面,按键查找元素很快;另一方面,您要获取的元素没有歧义。

order = sorted(list(range(len(l0))), key=lambda i: l0[i])
l1 = [l0[i] for i in order]

正如评论中所说,numpy.argsort做同样的事情。

要反转排列,您可以在 上重复相同的过程order

inverse_order = sorted(order, key=lambda i: order[i])
l0_again = [l1[i] for i in inverse_order]

显然,您可以使用相同的过程将另一个按l1顺序排列的列表重新l0排列:

ls_in_l0_order = [ls[i] for i in inverse_order]

推荐阅读