python如何返回排序列表的索引?

博客聚焦于Python中返回排序列表索引的问题,虽未给出具体内容,但核心围绕Python语言,探讨列表排序后获取索引的相关信息技术内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

>>> lis = [1,2,3,0,1,9,8]
>>> sorted(range(len(lis)), key=lambda k: lis[k])
[3, 0, 4, 1, 2, 6, 5]
>>>
<think>我们有两个需求:1. 对列表排序;2. 获取排序后每个元素在原始列表中的索引。 引用[1]中提供了一种方法,通过复制列表并逐步查找最小值,同时在复制列表中标记已找到的元素(赋0)来记录重复元素的索引。但这种方法在原始列表包含0时可能会出错(因为赋0后可能混淆),并且效率较低(每次循环都要找最小值,且删除元素操作也是O(n))。 引用[2]和[3]提到使用itemgetter和sorted函数结合enumerate来更高效地实现。 更高效且常用的方法是: 1. 使用enumerate生成带索引的元组列表,如:[(index, value), ...] 2. 根据元组的值(即value)进行排序 3. 排序后,提取索引部分即可得到原始索引 具体步骤: 步骤1:使用enumerate获取原始索引和元素 步骤2:利用sorted函数的key参数,指定根据元素值排序 步骤3:从排序后的元组列表中提取索引 注意:如果原列表有重复元素,这种方法会按照元素大小排序,对于相同的元素,sorted函数会保持它们在原列表中出现的相对顺序(即稳定排序),但如果我们不关心相同元素的顺序,也可以接受。 示例代码: ```python a = [13, 1, 5, 8, 9, 7, 5, 1, 4, 8, 7, 6, 5, 14, 5, 7, 9, 8, 9] # 生成带索引的元组列表 indexed_a = list(enumerate(a)) # 根据元组中的值排序(元组的第二个元素) sorted_indexed_a = sorted(indexed_a, key=lambda x: x[1]) # 提取排序后的索引 indices = [index for index, value in sorted_indexed_a] # 提取排序后的值(如果需要) sorted_a = [value for index, value in sorted_indexed_a] print("排序后的值:", sorted_a) print("对应的原索引:", indices) ``` 输出: 排序后的值: [1, 1, 4, 5, 5, 5, 5, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 13, 14] 对应的原索引: [1, 7, 8, 2, 6, 12, 14, 11, 5, 10, 15, 3, 9, 17, 4, 16, 18, 0, 13] 这与引用[1]中的结果一致,但代码更简洁高效。 另外,引用[4]中提到了sort()和sorted()的区别:sorted()不会修改原列表,而是返回一个新列表。 如果我们需要降序排序,只需在sorted函数中添加参数reverse=True: ```python sorted_indexed_a = sorted(indexed_a, key=lambda x: x[1], reverse=True) ``` 如果希望相同值的元素按照原始索引的升序排列(即先出现的排在前面),由于sorted是稳定排序,但这里我们根据值排序,相同值的情况下,sorted会保持原始顺序(即原列表中先出现的会在前面)。但是,如果我们希望相同值的元素按照索引从小到大排列,由于我们生成元组时索引是递增的,所以相同值的情况下,原始索引小的元组会先出现。因此,在排序时,如果值相同,sorted函数会按照元组在列表中的顺序(即原索引顺序)来排列。所以直接使用上述方法即可。 但是,如果我们需要在值相同的情况下按照索引降序排列,可以修改key函数: ```python sorted_indexed_a = sorted(indexed_a, key=lambda x: (x[1], -x[0])) ``` 这样,当值相同时,会按照索引的负值排序(即索引大的反而排在前面?)但这样会打乱稳定排序。实际上,我们可以通过设置多个条件: ```python sorted_indexed_a = sorted(indexed_a, key=lambda x: (x[1], x[0])) # 值相同按索引升序 # 或者 sorted_indexed_a = sorted(indexed_a, key=lambda x: (x[1], -x[0])) # 值相同按索引降序 ``` 不过,在大多数情况下,我们只需要值排序,相同值的顺序不重要,或者保持原顺序即可。 总结:使用enumerate和sorted是最简洁高效的方法。 引用[1]中的方法虽然可行,但效率较低(循环内每次找最小值并删除,时间复杂度为$O(n^2)$),而使用sorted方法的时间复杂度为$O(n \log n)$,更优。 因此,推荐使用sorted+enumerate的方法。</think>在Python中对列表排序并获取元素原始索引的高效方法是使用`enumerate()`结合`sorted()`函数,通过自定义排序键实现。以下是完整解决方案: ### 方法1:基本排序(保留重复元素顺序) ```python data = [13, 1, 5, 8, 9, 7, 5, 1, 4, 8, 7, 6, 5, 14, 5, 7, 9, 8, 9] # 创建(索引, 值)元组列表 indexed_data = list(enumerate(data)) # 按值排序(稳定排序保持重复元素顺序) sorted_data = sorted(indexed_data, key=lambda x: x[1]) # 提取排序后的值和原始索引 sorted_values = [val for _, val in sorted_data] original_indices = [idx for idx, _ in sorted_data] print("排序值:", sorted_values) print("原索引:", original_indices) ``` 输出: ``` 排序值: [1, 1, 4, 5, 5, 5, 5, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 13, 14] 原索引: [1, 7, 8, 2, 6, 12, 14, 11, 5, 10, 15, 3, 9, 17, 4, 16, 18, 0, 13] ``` ### 方法2:高级排序(控制相同元素的排序) ```python from operator import itemgetter data = [13, 1, 5, 8, 9, 7, 5, 1, 4, 8, 7, 6, 5, 14, 5, 7, 9, 8, 9] # 按值主排序索引排序(降序) sorted_data = sorted( enumerate(data), key=lambda x: (x[1], -x[0]), # 值升序,索引降序 reverse=False ) # 解包结果 sorted_values, original_indices = zip(*[(val, idx) for idx, val in sorted_data]) ``` ### 关键点说明 1. **核心原理** 通过`enumerate()`创建`(原始索引, 元素值)`元组,使用`sorted()`的`key`参数指定排序依据 2. **排序稳定性** Python的`sorted()`是[稳定排序](https://docs.python.org/3/library/functions.html#sorted)[^4],相同值的元素保持原始顺序 3. **时间复杂度** - 最优:$O(n \log n)$ (Timsort算法) - 空间:$O(n)$ (创建新列表) 4. **内存优化** 使用生成器表达式减少内存占用: ```python indices = [i for i, _ in sorted(enumerate(data), key=itemgetter(1))] ``` ### 应用场景 1. 数据科学中匹配排序后的特征与原始样本 2. 算法竞赛中需要输出排序后位置 3. 时间序列分析中保持时间戳对应关系 > 引用说明:方法1基于`enumerate()`和`sorted()`的标准用法[^2][^3],方法2展示了多条件排序技巧[^2][^4]
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

凯旋的皇阿玛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值