【发布时间】:2018-01-21 04:45:42
【问题描述】:
我从 Google 发布的速成课程开始自学 Python。练习题之一是编写一个函数,它接受 2 个 sorted 列表,将它们合并在一起,然后返回一个有序列表。最明显的解决方案是:
def linear_merge(list1, list2):
list = list1 + list2
list.sort()
return list
显然上面的效率不是很高,或者我是这么认为的,因为在后端,排序函数将不得不再次遍历整个输出列表。问题需要一种有效的方法来实现这个功能,大概它可以在巨大的列表上很好地工作。我的代码类似于 Google 的答案,但我对其进行了一些调整以使其更快:
def linear_merge_goog(list1, list2):
result = []
while len(list1) and len(list2):
if list1[-1] > list2[-1]:
result.append(list1.pop())
else:
result.append(list2.pop())
result.extend(list1)
result.extend(list2)
return result[::-1]
原始的 Google 代码是从数组的前面弹出的,但即使他们也注意到从数组的后面弹出而不是反转它更有效。
我尝试用 2000 万个大型条目数组运行这两个函数,而简单愚蠢的组合和排序函数每次都以 3 倍以上的优势排在首位。对于应该更有效的方法,不到 1 秒与超过 3 秒。
有什么想法吗?我是不是错过了什么。它是否与在解释我的代码时编译的内置排序函数有关(听起来不太可能)。还有其他想法吗?
【问题讨论】:
-
所以你说线性合并更快?这两个子列表是排序的,对吧?
-
另外,很有可能。 python timsort 代码是用 C 编写的,经过高度优化,速度非常快,尤其是对于几乎排序的列表。相反,在非连续结构上执行操作的合并速度很慢。它不太可能更快。
-
是的,2 个子列表已排序,因此排序方法应该比手动合并慢,但事实并非如此,它要快得多。正如你提到的,我认为这只是 C 的优势。
标签: python arrays list sorting performance-testing