Python quicksort-列表理解与递归(分区例程)
问题内容:
我看了谈话“三个美丽的快速排序”,并开始忙于快速排序。我在python中的实现与c非常相似(选择数据透视图,围绕它的分区并在越来越大的分区上递归)。我以为不是
pythonic 。
所以这是在python中使用列表理解的实现。
def qsort(list):
if list == []:
return []
pivot = list[0]
l = qsort([x for x in list[1:] if x < pivot])
u = qsort([x for x in list[1:] if x >= pivot])
return l + [pivot] + u
让我们将递归称为qsortR。现在我注意到对于大型列表,qsortR的运行速度比qsort慢得多。实际上,对于递归方法,即使对于1000个元素,“最大递归深度都超过了cmp”。我在sys.setrecursionlimit中重置了它。
一些数字:
list-compr 1000 elems 0.491770029068
recursion 1000 elems 2.24620914459
list-compr 2000 elems 0.992327928543
recursion 2000 elems 7.72630095482
所有代码都在这里。
我有一些问题:
- 为什么列表理解如此之快?
- 对python递归限制的一些启示。在某些情况下,我首先将其设置为100000?
- (“优化尾递归”到底是什么意思,如何完成?)
- 尝试对1000000个元素进行排序占用了我的笔记本电脑的内存(使用递归方法)。如果我想对这么多元素排序,该怎么办?什么样的优化是可能的?
问题答案:
- 为什么列表理解如此之快?
因为列表理解意味着C循环,它比使用Pythonfor
块的慢速通用方法要快得多。
- 对python递归限制的一些启示。 在某些情况下,我首先将其设置为100000?
万一您的内存不足。
- 尝试对1000000个元素进行排序占用了我的笔记本电脑的内存(使用递归方法)。 如果我想对这么多元素排序,该怎么办?什么样的优化是可能的?
Python的递归带来了这样的开销,因为每个函数调用都会在每个调用上分配大量的堆栈内存空间。
一般而言,迭代就是答案(在统计上99%的用例中,其性能都会更好)。
谈到内存结构,如果您有简单的数据结构,例如chars,integers,floats:请使用内置函数,array.array
它比a的内存效率高得多list
。