我从Google发布的速成课程开始教我自己的Python。其中一个实践问题是编写一个带有2个排序列表的函数,将它们合并在一起,然后返回一个排序列表。最明显的解决方案是:
def linear_merge(list1, list2):
list = list1 + list2
list.sort()
return list
显然上面的效率不是很高,或者我认为,因为在后端,sort函数必须再次运行整个输出列表。该问题要求实现此功能的有效方法,可能是它可以在巨大的列表上很好地工作。我的代码与谷歌的答案类似,但我稍微调整一下以使其更快一点:
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秒。
有什么想法吗?我错过了什么。是否与我的代码被解释时编译的内置排序函数有关(听起来不太可能)。还有其他想法吗?
答案 0 :(得分:6)
由于.sort()
的Python实现。 Python使用名为Timsort的东西。
Timsort是一种合并方式。它的显着特点是它识别"运行"它用于合并的预分类数据。在实际数据中,未排序数据中的已排序运行非常常见,如果预先排序,则可以在 O(n)时间内对两个已排序的数组进行排序。这可以大大减少通常在 O(nlog(n))时间运行的排序时间。
所发生的事情是,当您在Python中call list.sort()
时,它会识别两组排序数据list1
和list2
,并将它们合并到 O( n)时间。另外,这个实现是编译的C代码,它比执行相同操作的解释Python实现更快。