用python优雅实现:序列A依照序列B排序

简介: 序列排序是日常开发常见的需求。实现方式有很多,哪种方式最简洁明了?需求:已知序列A、B拥有相同的元素,要求序列A依照序列B排序进行排序。

序列排序是日常开发常见的需求。实现方式有很多,哪种方式最简洁明了?


需求:已知序列A、B拥有相同的元素,要求序列A依照序列B排序进行排序。

# 假设序列 A 和序列 B 是如下:
A = [4, 1, 6, 3, 5, 2]
B = [1, 2, 3, 4, 5, 6]

冒泡排序

通过重复遍历待排序列表,比较相邻元素,交换顺序错误的元素,逐步将最大或最小的元素“冒泡”到列表的一端,就像气泡在液体中上升一样。

# 复制 A 以避免修改原列表
sorted_A = A[:]  

# 参照冒泡排序算法
for i in range(len(sorted_A)):
    for j in range(i + 1, len(sorted_A)):
        # 检索A中元素在B的位置
        if B.index(sorted_A[i]) > B.index(sorted_A[j]):
            sorted_A[i], sorted_A[j] = sorted_A[j], sorted_A[i]

print(sorted_A)  # 输出: [1, 2, 3, 4, 5, 6]

使用内置函数sorted

相对于冒泡排序,内置函数sorted简洁而高效


简洁:如下使用少量的代码,实现等效的排序。

sorted_A = sorted(A, key=lambda x: B.index(x))
print(sorted_A)  # 输出: [1, 2, 3, 4, 5, 6]

高效:sorted函数是线性对数时间复杂度 𝑂(𝑛log⁡𝑛),冒泡算法属于平方时间复杂度 𝑂(𝑛2)。排序的数量级越大,sorted函数优势越明显。


PS: Python 内置的 sorted 函数以及列表的 sort 方法都使用了一种叫做 Timsort 的排序算法。以下是 sorted 函数的详细介绍及其使用方法:

sorted(iterable, key=None, reverse=False)

  1. iterable: 这是必需参数。可以是任何可迭代对象,如列表、元组、字符串、字典等。
  2. key: 这是一个可选参数。它是一个函数,作用于 iterable 参数中的每一个元素,sorted 函数将使用该函数的返回值进行排序。
  3. reverse: 这是一个可选参数。它是一个布尔值。如果设置为 True,则按照降序排序。默认为 False(升序排序)。

适配元素不存在情况

生产环境中,可能存在序列A中元素不在序列B中。对于这种情况,使用以上代码会抛出异常。

例如:

A = [4, 1, 6, 3, 5, 7]
B = [1, 2, 3, 4, 5, 6]
sorted_A = sorted(A, key=lambda x: B.index(x))

Traceback (most recent call last):
  File "<input>", line 3, in <module>
  File "<input>", line 3, in <lambda>
ValueError: 7 is not in list

根据墨菲定律(如果有什么事情可能出错,那么它就很有可能会出错),应该进行防御式编程,做相应适配。


使用if做预先判断

A = [4, 1, 6, 3, 5, 7]
B = [1, 2, 3, 4, 5, 6]
# 当序列A中元素不在序列B时,默认排在最后
default_index = len(B) + 1

# 定义一个普通函数作为排序的关键字函数
def sort_key(x):
    return B.index(x) if x in B else default_index

sorted_A = sorted(A, key=sort_key)
print(sorted_A)  # 输出: [1, 3, 4, 5, 6, 7]

使用try except捕获异常

A = [4, 1, 6, 3, 5, 7]
B = [1, 2, 3, 4, 5, 6]
# 当序列A中元素不在序列B时,默认排在最后
default_index = len(B) + 1
# 定义一个普通函数作为排序的关键字函数
def sort_key(x):
    try:
        return B.index(x)
    except ValueError:
        return default_index
sorted_A = sorted(A, key=sort_key)
print(sorted_A)  # 输出: [1, 3, 4, 5, 6, 7]

转换成字典使用get方法

A = [4, 1, 6, 3, 5, 7]
B = [1, 2, 3, 4, 5, 6]
# 当序列A中元素不在序列B时,默认排在最后
default_index = len(B) + 1
# 创建一个字典来存储 B 中每个元素的索引
index_map = {value: idx for idx, value in enumerate(B)}
# 使用这个字典来对 A 进行排序
sorted_A = sorted(A, key=lambda x: index_map.get(x, default_index))
print(sorted_A) # 输出: [1, 3, 4, 5, 6, 7]

总结

对比三种方式:

  • 性能:字典方法 (get) 最优,if 判断其次,try-except 最差。
  • 可读性if 判断和字典方法较好,try-except 相对较差。
  • 空间复杂度:字典方法需要额外空间,其它两种方法不需要。


  1. 异常处理在 Python 中相对较慢
  2. python字典因为使用哈希表(Hash Table)这种数据结构的原因,时间复杂度是常量级的。是一种以空间换时间的实现方式。优点是速度非常快,缺点是消耗额外内存。


综合考虑性能和可读性,使用字典转换 (get 方法) 是三者中最优的选择。它在性能上占据优势,并且代码简洁直观,易于维护。

相关文章
|
5月前
|
存储 数据采集 大数据
Python推导式进阶指南:优雅初始化序列的科学与艺术
本文系统讲解Python推导式的用法与技巧,涵盖列表、字典、集合推导式及生成器表达式。通过代码示例和性能对比,展示推导式在数据结构初始化中的优势:简洁高效、执行速度快30%-50%。文章分析基础语法、核心应用场景(如序列构造、键值对转换、去重运算)及嵌套使用,并探讨使用边界与最佳实践,强调可读性优先原则。最后指出,合理运用推导式能显著提升代码质量和处理效率,同时避免过度复杂化的陷阱。
110 0
|
机器学习/深度学习 数据采集 算法
时间序列结构变化分析:Python实现时间序列变化点检测
在时间序列分析和预测中,准确检测结构变化至关重要。新出现的分布模式往往会导致历史数据失去代表性,进而影响基于这些数据训练的模型的有效性。
1313 1
|
8月前
|
存储 索引 Python
Python入门:6.深入解析Python中的序列
在 Python 中,**序列**是一种有序的数据结构,广泛应用于数据存储、操作和处理。序列的一个显著特点是支持通过**索引**访问数据。常见的序列类型包括字符串(`str`)、列表(`list`)和元组(`tuple`)。这些序列各有特点,既可以存储简单的字符,也可以存储复杂的对象。 为了帮助初学者掌握 Python 中的序列操作,本文将围绕**字符串**、**列表**和**元组**这三种序列类型,详细介绍其定义、常用方法和具体示例。
Python入门:6.深入解析Python中的序列
|
机器学习/深度学习 算法 数据挖掘
6种有效的时间序列数据特征工程技术(使用Python)
在本文中,我们将探讨使用日期时间列提取有用信息的各种特征工程技术。
373 1
|
9月前
|
数据挖掘 数据处理 开发者
Python3 自定义排序详解:方法与示例
Python的排序功能强大且灵活,主要通过`sorted()`函数和列表的`sort()`方法实现。两者均支持`key`参数自定义排序规则。本文详细介绍了基础排序、按字符串长度或元组元素排序、降序排序、多条件排序及使用`lambda`表达式和`functools.cmp_to_key`进行复杂排序。通过示例展示了如何对简单数据类型、字典、类对象及复杂数据结构(如列车信息)进行排序。掌握这些技巧可以显著提升数据处理能力,为编程提供更强大的支持。
360 10
|
机器学习/深度学习 索引 Python
python之序列
python之序列
223 59
|
11月前
|
搜索推荐 Python
快速排序的 Python 实践:从原理到优化,打造你的排序利器!
本文介绍了 Python 中的快速排序算法,从基本原理、实现代码到优化方法进行了详细探讨。快速排序采用分治策略,通过选择基准元素将数组分为两部分,递归排序。文章还对比了快速排序与冒泡排序的性能,展示了优化前后快速排序的差异。通过这些分析,帮助读者理解快速排序的优势及优化的重要性,从而在实际应用中选择合适的排序算法和优化策略,提升程序性能。
302 1
|
12月前
|
存储 C++ 索引
Python 序列类型(1)
【10月更文挑战第8天】
126 1
|
12月前
|
存储 编译器 索引
Python 序列类型(2)
【10月更文挑战第8天】
79 0
Python 序列类型(2)
|
Python
Python中几种lambda排序方法
【9月更文挑战第7天】在Python中,`lambda`表达式常用于配合排序函数,实现灵活的数据排序。对于基本列表,可以直接使用`sorted()`进行升序或降序排序;处理复杂对象如字典列表时,通过`lambda`指定键值进行排序;同样地,`lambda`也适用于根据元组的不同位置元素来进行排序。
592 1

推荐镜像

更多