Software Engineering

How to Write a Custom Comparator in Python

Generally, you want to use the built-in sorted() function which takes a custom comparator as its parameter. We need to pay attention to the fact that in Python 3 the parameter name and semantics have changed.

How the custom comparator works

When providing a custom comparator, it should generally return an integer/float value that follows the following pattern (as with most other programming languages and frameworks):

  • return a negative value (< 0) when the left item should be sorted before the right item
  • return a positive value (> 0) when the left item should be sorted after the right item
  • return “ when both the left and the right item have the same weight and should be ordered “equally” without precedence

The challenge

Write a comparator for a list of phonetic words for the letters of the greek alphabet.

A comparator is:

a custom comparison function of two arguments (iterable elements) which should return a negative, zero or positive number depending on whether the first argument is considered smaller than, equal to, or larger than the second argument


The greek alphabet is preloded for you as greek_alphabet:

greek_alphabet = (
    'alpha', 'beta', 'gamma', 'delta', 'epsilon', 'zeta', 
    'eta', 'theta', 'iota', 'kappa', 'lambda', 'mu', 
    'nu', 'xi', 'omicron', 'pi', 'rho', 'sigma',
    'tau', 'upsilon', 'phi', 'chi', 'psi', 'omega')


greek_comparator('alpha', 'beta')   <  0
greek_comparator('psi', 'psi')      == 0
greek_comparator('upsilon', 'rho')  >  0

Test cases

test.expect(greek_comparator('alpha', 'beta') < 0, "result should be negative")
test.assert_equals(greek_comparator('psi', 'psi'), 0)
test.expect(greek_comparator('upsilon', 'rho'), "result should be positive")

The solution in Python

Option 1 (using index):

def greek_comparator(lhs, rhs):
    return greek_alphabet.index(lhs) - greek_alphabet.index(rhs)

Option 2 (using cmp):

def greek_comparator(lhs, rhs):
    return cmp(greek_alphabet.index(lhs), greek_alphabet.index(rhs))

Option 3 (using map/reduce):

def greek_comparator(*args):
    return reduce(int.__sub__, map(greek_alphabet.index, args))