How to sort a list? NOT a newbie question.
Michael James Barber
mjbarber at ascc.artsci.wustl.edu
Mon Sep 17 06:09:21 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
More information about the Python-list
mailing list