sort() comparison lambda for floats/longs

Tim Peters tim.one at comcast.net
Mon Jul 29 19:11:04 EDT 2002


[Jack Diederich]
> I had to sort a list of list of floats (Nx2 array)
> but I couldn't find a comparison function that would take
> a little error delta to do the std C-style comparison
>
> if (a + delta > b && a - delta < b) {
>    printf("Yeah, a == b");
> }
>
> here is a lambda I am using in a list.sort()
> delta_cmp = lambda a,b,delta=0.00001:
>   int((((a+delta) > b and (a-delta) < b) and '0') or
>       (a > b and 1) or
>       (a < b and -1)
>       )
>
> The int() is needed to turn the '0' from true into zero
> It uses the side effects of 'or' and 'and' to return 0/1/-1

Brrrrrr.  Throw that away before it breeds <wink>.

def delta_cmp(a, b, delta=0.00001):
    if abs(a-b) < delta:
        return 0
    else:
        return cmp(a, b)

does the same thing, but without trickery.  Note that there's nothing
magical about a lambda expression -- it's exactly the same as a named
function except for lacking a name <wink>, and .sort() couldn't care less
whether you pass it a lambda expression or the name of a comparison
function.  The runtime is the same either way too.

> I need the delta because I'm also sorting on the second
> column, which could be an int or string, or anything.

Sorry, couldn't follow this part.  Careful input -> desired_output examples
would be clearer than prose.

> If it was just a single list of floats then a compare without
> a delta would work because all the nearly-equal values would
> still be next to each other.

Ditto.

> to sort this
> ll = [[1.0, 'A'],
>       [2.0, 'B']]
>
> I would do
> ll.sort(lambda a,b: delta_cmp(a[0],b[0]) or  cmp(a[1], b[1]))
>
> Is there a better way to do this in python?

It's completely unclear to me why plain

    ll.sort()

doesn't do what you want.  That automatically sorts on "the first column" as
the primary key, and looks at "the second column" too if and only if two
"rows" have identical values in the first column.  The result will be sorted
in increasing order of first column, with ties in the first column resolved
by increasing order of second column.  If you don't think plain .sort() does
do what you want, then you really need to give us a specific example where
it doesn't do what you want, and show us exactly what you do want instead.





More information about the Python-list mailing list