如何让这个天真的python实现Quicksort更加pythonic?

Fra*_*ery 2 python quicksort

我在阅读diveintopython的两个小时后,我实现了一个天真的快速版本.

import operator

def even(num):
    return operator.mod(num,2) == 0

def last(list):
    return len(list)-1

def median(list):
    if even(len(list)):
        return len(list)/2 - 1
    else:
        return len(list)/2

def sort(list, pivot_selector):
    if len(list) <= 1:
        return list
    else:
        i = pivot_selector(list)
        pivot = list[i]
        less, greater, equal = [], [], []
        for x in list:
            if x < pivot:
                less.append( x )
            elif x == pivot:
                equal.append( x )
            else:
                greater.append( x )

    return sort(less, pivot_selector) + equal + sort(greater, pivot_selector)

if __name__ == "__main__":
    print sort([5,4,3,2],median)
    print sort([],median)
    print sort([2],median)
    print sort([3,2],median)
    print sort([3,2,3],median)
    print sort([1,3,2],median)
    print sort([1,'a',0],median)
    print sort([None,1,0],median)
Run Code Online (Sandbox Code Playgroud)

5个问题:

  1. 此代码驻留在名为quicksort.py的文件中.如何将方法隐藏起来甚至导出到公众中.
  2. 传递*pivot_selector*作为参数是pythonic吗?
  3. 我的快速配置实施有什么不对或不合适吗?
  4. 您如何允许用户指定一个比较器,该比较器将对列表元素强制执行自定义排序?
  5. 是否有一种pythonic方法来强制执行list参数必须包含同类型的约束?

Dav*_*ebb 5

1 - 此代码驻留在名为quicksort.py的文件中.如何将方法隐藏起来甚至导出到公众中.

惯例是在您的模块中将函数命名为private,并在开头使用下划线.

2 - 传递*pivot_selector*作为参数是pythonic吗?

由于Python具有第一类函数,因此可以将函数作为参数传递.

3 - 我的快速排序实施有什么不对或不合适吗?

equal列表的使用对我来说似乎不是传统的. 通常等于枢轴的项目最终会出现在greater列表中.

4 - 您如何允许用户指定一个比较器,该比较器将对列表元素强制执行自定义排序?

标准Python sort()sorted()函数具有比较函数的可选参数.这似乎是最好的方法.

5 - 是否有一种pythonic方法来强制执行约束,list参数必须包含同类型?

在Python中,您通常不担心这一点.Python具有duck-typing概念,因此如果一个对象做了它应该做的事情,我们不担心事先检查它的类型.这通常表达为"请求宽恕比允许更容易".

因此,让模块的用户担心如果他们传入一个无法相互比较的对象列表,则会抛出异常.