How to sort a list? NOT a newbie question.

Ken Seehof kseehof at neuralintegrator.com
Mon Sep 17 13:30:08 EDT 2001


> All in Python 2.1.1:
>
> >>> l1 = [1, '1j', [1,'1j']]
> >>> l1.sort()
> >>> print l1
> [1, [1, '1j'], '1j']
>
> >>> l2 = [1, 1j, [1,'1j']]
> >>> l2.sort()
> Traceback (most recent call last):
>   File "<input>", line 1, in ?
> TypeError: cannot compare complex numbers using <, <=, >, >=
>
>
> This came up in the context of building the coefficients of polynomials
> from a list of roots.  If complex roots occur in complex conjugate pairs,
> then the resulting coefficients must be real, so I decided to cast the
> coefficients to floats in this case.  A straightforward test is to take
> the complex conjugate of each element of the list, then sort both lists
> and see if they are the same.  As is clear from the above, that definitely
> didn't work!
>
> For the particular problem I was working on, it was simple to find a
> workaround that was only slightly awkward.  I don't have any idea how to
> address the case shown above.  Admittedly, it is largely a rhetorical
> question, but what do people think is the "one obvious way" to sort such
> a list?  The goal is an "arbitrary but deterministic" sort, much like with
> other heterogeneous lists.
>
>
> In a larger sense, this is a frustrating aspect of Python's numerical
> model.  PEP 228 looks like a good start on treating all numbers just as
> numbers, without the surprises that can arise now.  But where do
> comparisons of complex numbers fit in?  Is it better to be mathematically
> correct and raise an exception, or to have complex numbers respond in a
> useful, but not really correct, fashion to all comparisons?
>
> I've used Matlab extensively for about 8 years (although a lot less often
> since discovering Python and Numeric about a year ago!).  In Matlab,
> complex numbers are sorted based on their magnitudes, and then by phase
> angle if the magnitudes are the same.  Comparing complex numbers using <,
> <=, >, and >= always returns false.  I've known about the sorting for
> quite a while, but only learned about the behavior of the comparison
> operators after discovering Python's behavior yesterday.  While not
> strictly correct mathematically, I suspect that Matlab's approach is a
> good practical approach, since it took me so long to notice.  I don't know
> what Mathematica and others do.
> --
> Michael J. Barber

I agree.  The current approach of raising an exception is inconsistent with
all other sorting protocols in python.  You can sort by tuples, types, and
even heterogeneous data!  So why should complex numbers be so special?

Complex numbers should be sortable even though it doesn't seem to make
mathematical sense to some people.  Of course, all multi-dimensional
domains -are- sortable: it is just a matter of selecting the sort keys.

For compatibility, Matlab's approach (A, theta) is tempting, but this
would not be compatible with python thinking (especially the new way
of looking at numbers(whether you agree with this new way or not)).
I was thinking that sorting by (real, imag) would be more appropriate,
that way 2 behaves the same as (2.0+0.0j), which is necessary for
the grand numeric unification.

Matlab says that you can sort, but not compare complex numbers.
This won't work in python because sorting and comparing are the
same thing.

Sorting complex numbers feels mathematically strange to me; I'm not
saying that it doesn't.  But the current policy of raising an exception is
based on a false premise: that "(2.0+1.0j) > (2.0+0.9j)" makes less
sense than "type(3.4) > ['spam', 52]".

Hmm, how about sensibility sorting?  :-)

    if sensibility("type(3.4) > 'spam'") > sensibility("2.0+1.0j > 2.0"):
        run_away_run_away()

Obviously the policy of python is that all things are sortable.  I really
can't imagine how complex numbers got left out.

Finally, there is the practical argument: Michael has given an example
of useful sorting of complex numbers.  To counter this, someone must
show an example of a realistic hypothetical bug where a programmer
accidentally sorts or compares complex numbers with devastating
results which would have been avoided if an exception had been
raised.

All experienced programmers know this:
   importance(consistency) > importance(sensibility)

Is there a PEP for this?  I couldn't find one.  It doesn't seem to be part
of 228, though obviously it would be a requirement for 228.  If nobody
responds to me that a PEP already exists, I'll make one.

- Ken






More information about the Python-list mailing list