Complex 'compare'

Avi Gross avigross at verizon.net
Tue Dec 18 09:59:51 EST 2018


Frank,

Thanks for explaining.

It looks like you might want a shortcut compare done in an iterative or
recursive way that returns as soon as a discrepancy happens in the direction
you are comparing. If they are equal, you fall off the end.

A pythonic way is to use a loop as in:

>>> flag = True
>>> for alpha, beta in zip(first, second):
	if (alpha < beta):
		flag = False
		break

The above is not the full code, just an example. In that loop you would need
to check for None or anything else. You need to determine if the match was
found or if it is less than versus greater than so you can continue your
binary search.

There are many tricks (ahem, techniques) people use. Some compare functions
that need to return a trinary answer will return 1 for Greater than, -1 for
Less than and 0 for equal. The function calling it can use techniques to
branch based on that such as using the return code to index a dictionary
containing keys -1,0, and 1 and a value that is the function to call to
fetch the next item above or below. 

Another method could be to have the function return a tuple of results. If
you return (found, comparison) as in:

(found, comparison) = function(...)

Then if the two are equal, return True in the first variable and if it is
False, examine the second variable to see if it is True or False.

And, of course, you can just do two comparisons in the first place. One for
"==" to find if you found it and the other for a test to see if you need to
search before or after the current cursor.

The quality test might work well in a try statement. Something like this
works fine:

>>> (1,1, None) == (1,1,None)
True

And it seems resistant to many errors because it is testing equality and
objects of different types are often by definition not equal.

>>> (1,1, None) == (1,1,None)
True
>>> (1,1, 2) == (1,1,None)
False
>>> (1,1, "two") == (1,1,2)
False
>>> (1,2) == (1,2,3)
False

If you want to make sure some other errors do not creep in, place it in a
try/catch statement as any error would also be a false.

Just some thoughts.




-----Original Message-----
From: Python-list <python-list-bounces+avigross=verizon.net at python.org> On
Behalf Of Frank Millman
Sent: Tuesday, December 18, 2018 6:39 AM
To: python-list at python.org
Subject: Re: Complex 'compare'

"Chris Angelico"  wrote in message
news:CAPTjJmpLuyFf04AT+34VraJ5itDvNySVJspEv=DdWDSMMSF88w at mail.gmail.com...
>
> On Tue, Dec 18, 2018 at 9:52 PM Frank Millman <frank at chagford.com> wrote:
> > I need to know if one row is greater than or less than the other. 
> > The sort sequence can be complex - one or more columns, each of 
> > which can be sorted ascending or descending.
> >
> > Below is the function I have come up with. Can anyone see any 
> > problem with it, or suggest a better way to do it?
>
> I'm not sure what the difference is between "compare_type" and "desc".
> You have four options here:
>
> * gt, desc
>     True if source_col is None else source_col < target_col
> * gt, not desc
>     False if source_col is None else source_col > target_col
> * lt, desc
>     False if source_col is None else source_col > target_col
> * lt, not desc
>     True if source_col is None else source_col < target_col
>
> The way this is currently coded, these come in two perfect pairs.
>

Yes, now that you point it out, there is definitely scope for shortening the
code, as that is effectively duplication.

My main concern was whether my algorithm had any flaws in it. I will keep
testing to look for corner cases.

I can assume total ordering. The background is that I want to find the
position of a row in a table according to some sequence. I can't read in the
entire table, as it could contain millions of rows. So I create a
server-side cursor in the desired sequence, and then perform a binary search
on it. So far it is working well.

Thanks

Frank


--
https://mail.python.org/mailman/listinfo/python-list



More information about the Python-list mailing list