对含原索引的列表排序后,如何高效生成原索引映射列表?
高效生成排序后的索引映射列表
嘿,这个场景我经常遇到!先给你直接上最高效的实现,再拆解为什么它比手动方式好:
核心思路
你已经用srt.sort()完成了排序(Python列表默认的排序逻辑就是按元素的自然顺序逐个比较,刚好符合你按n0、n2……ni排序的需求),接下来生成索引映射的关键是用底层优化的列表推导式替代手动循环,这能直接把效率拉满。
完整代码示例
假设你的原始列表是这样的:
oList = [[3, 1], [2, 4], [1, 5], [3, 0]] # 先构建带原始索引的srt列表(用enumerate更简洁) srt = [list(item) + [idx] for idx, item in enumerate(oList)] # 按数字项排序(默认排序就符合要求) srt.sort() # 高效生成索引映射列表 idx_map = [item[-1] for item in srt]
运行后idx_map会是[3, 2, 1, 0],对应排序后每个元素的原始索引。
为什么这比手动方式高效?
- 列表推导式
[item[-1] for item in srt]是用C语言实现的循环,比你手动写for item in srt: idx_map.append(item[-1])快得多——尤其是当你的列表规模很大时,这种底层优化的优势会非常明显。 - 如果不想修改原
srt列表,也可以一步到位,用sorted函数直接生成映射:idx_map = [item[-1] for item in sorted(srt)]
进阶优化(针对超大规模数据)
如果你的oList特别大(比如百万级元素),可以用operator.itemgetter稍微优化排序的速度(虽然默认排序已经很快了,但能再提一点):
from operator import itemgetter # 按前n-1项排序(n是srt元素的长度,也就是原始数字项的数量+1) srt.sort(key=itemgetter(*range(len(srt[0])-1)))
不过其实Python默认的列表排序已经会逐个比较元素的子项,所以这个优化的收益不算特别大,但聊胜于无。
内容的提问来源于stack exchange,提问作者Markus_13
相关产品推荐
相关产品推荐

