如何使用自定义归并排序函数对元组列表按指定元素排序?
按元组指定元素用自定义归并排序实现排序
Hey there! 我来帮你把自定义的归并排序函数改成支持按元组第3个元素排序的版本~
你原来用activity_arr.sort(key=operator.itemgetter(2))能轻松实现按元组索引2的元素排序,核心是sort方法支持传入key参数指定排序依据。要让自己的merge_sort函数实现同样的效果,我们只需要给它加上自定义排序键的逻辑就行。
步骤1:修改归并排序函数,添加key参数
我们要给merge_sort新增一个可选的key参数,默认值为None(表示默认按元素本身排序)。在合并两个子数组的时候,先通过key函数转换元素,再进行比较。
修改后的完整代码如下:
def merge_sort(array, key=None): ''' Sorts an array using merge sort algorithm, with optional key function.''' if len(array) > 1: mid = len(array) // 2 left = array[:mid] right = array[mid:] # 递归排序左右子数组,同时传入key参数 merge_sort(left, key=key) merge_sort(right, key=key) i = j = k = 0 # 合并两个已排序的子数组 while i < len(left) and j < len(right): # 如果指定了key,就用key转换元素后再比较 left_val = key(left[i]) if key is not None else left[i] right_val = key(right[j]) if key is not None else right[j] if left_val <= right_val: array[k] = left[i] i += 1 else: array[k] = right[j] j += 1 k += 1 # 复制左子数组剩余元素 while i < len(left): array[k] = left[i] i += 1 k += 1 # 复制右子数组剩余元素 while j < len(right): array[k] = right[j] j += 1 k += 1
步骤2:调用修改后的merge_sort实现按元组索引2排序
现在你可以像用内置sort方法一样,传入key参数来指定排序依据。有两种常用方式:
方式1:用lambda函数指定索引
直接写一个lambda函数取出元组的第3个元素(索引为2):
# 示例元组列表 activity_arr = [('task1', 'morning', 3), ('task2', 'afternoon', 1), ('task3', 'evening', 2)] # 按元组索引2的元素排序 merge_sort(activity_arr, key=lambda x: x[2]) # 排序后结果:[('task2', 'afternoon', 1), ('task3', 'evening', 2), ('task1', 'morning', 3)] print(activity_arr)
方式2:用operator.itemgetter(和你原来的用法一致)
如果你习惯用operator.itemgetter,也可以直接传入:
import operator merge_sort(activity_arr, key=operator.itemgetter(2))
原理说明
新增的key参数让我们可以灵活指定排序的“依据值”:在合并阶段比较元素时,不再直接比较元组本身,而是先通过key函数把元组转换成我们想要的排序字段(这里就是元组的第3个元素),再用转换后的值进行比较,这样就实现了和内置sort方法一致的按指定字段排序的效果。
内容的提问来源于stack exchange,提问作者H.W.D
相关产品推荐
相关产品推荐

