Question: I'm 2 hours into my reading of *diveintopython* and I implemented a naive version of quicksort. 

```
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)

```

5 questions:

1. This code resides in a file called quicksort.py. How does one hide the method *even* from being exported to the public.
2. Is it pythonic to pass in a \*pivot\_selector\* as a parameter ?
3. Anything wrong or suboptimal with my quicksort implementation ?
4. How would you allow the user to specify a comparator that will enforce a custom ordering on the list elements ?
5. Is there a pythonic way to enforce a constraint that the list parameter must contain homogeneous types ?

Answer: 
> 
> 1 - This code resides in a file called quicksort.py. How does one hide the method even from being exported to the public.
> 
> 
> 

The convention is to name functions private to your module [with an underscore at the beginning](http://docs.python.org/tutorial/modules.html#more-on-modules).

> 
> 2 - Is it pythonic to pass in a \*pivot\_selector\* as a parameter ?
> 
> 
> 

Since Python has first class functions it's fine to pass functions around as parameters.

> 
> 3 - Anything wrong or suboptimal with my quicksort implementation ?
> 
> 
> 

The use of an `equal` list seems non-traditional to me. [Usually items equal to the pivot end up in the `greater` list.](http://en.wikipedia.org/wiki/Quicksort)

> 
> 4 - How would you allow the user to specify a comparator that will enforce a custom ordering on the list elements ?
> 
> 
> 

The standard Python `sort()` and [`sorted()`](http://docs.python.org/library/functions.html#sorted) functions have an optional parameter for a comparison function. This seems the best way to do it.

> 
> 5 - Is there a pythonic way to enforce a constraint that the list parameter must contain homogeneous types ?
> 
> 
> 

In Python you normally don't worry about this. Python has the [concept of duck-typing](http://docs.python.org/glossary.html#term-duck-typing), so if an object does what it's supposed to we don't worry about checking its type beforehand. This is often expressed as "It's easier to ask for forgiveness than permission."

So let the user of your module worry about the Exception that will be thrown if they pass in a list of objects to sort which can't be compared to each other.
1. You don't hide things in Python, we are all consenting adults here. If you really don't want to export it, you could make it an inner function (declare it inside the function you are using it).
2. I don't see why it wouldn't be pythonic. Passing function parameters is commonly used through all the Python API (e.g. `sort`'s `key` argument)
3. Yes, your median should be called "middle". And of course, as you probably already know, you could sort it in place and replace recursion with a stack based iteration, that will be a little bit faster (as the call stack frames are heavier to push and pop than just the arguments than change).
4. The same as with your pivot selector argument, pass a function that takes two arguments and returns true if the arguments are in order.
5. No, but you can raise an exception if you wish. If you really, really want to, you can use **numpy** arrays, that are ensured to be homogeneous.