<div dir="ltr"><div class="markdown-here-wrapper" style=""><p style="margin:0px 0px 1.2em!important">This sort of “multiple ways to compare the same data type” is a big part of why the <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline">list.sort</code> and <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline">sorted</code> functions can take an argument <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline">key</code>, which is a callable which returns a surrogate value to compare, e.g. a tuple of the fields to compare, or a proxy object whose comparison methods yield the current ordering of interest. </p>
<p style="margin:0px 0px 1.2em!important">Python 2 also offers a <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline">cmp</code> optional, which is analogous to the function passed to C’s <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline">quicksort</code>, a callable which decides which object is larger, and returns -1, 0, or 1 to indicate which. This was removed in Python 3, but <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline">functools.cmp_to_key</code> can convert a callable that behaves like <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline">cmp</code> into one that just returns surrogate values that satisfy its requirements, making it compatible with the <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline">key</code> argument to those sorting methods.</p>
<p style="margin:0px 0px 1.2em!important">That said, sorting intervals is application specific, since it really depends upon what you’re doing with said intervals. An Interval Tree or Segment Tree data structure would be appropriate for fast testing for interval overlap/point inclusion tests. For other problems, you might need more metadata when evaluating interval queries, requiring something more tailored. I’ve attached an Interval Tree implementation I use that might be useful for you too.</p>
<div title="MDH:VGhpcyBzb3J0IG9mICJtdWx0aXBsZSB3YXlzIHRvIGNvbXBhcmUgdGhlIHNhbWUgZGF0YSB0eXBl
IiBpcyBhIGJpZyBwYXJ0IG9mIHdoeSB0aGUgYGxpc3Quc29ydGAgYW5kIGBzb3J0ZWRgIGZ1bmN0
aW9ucyBjYW4gdGFrZSBhbiBhcmd1bWVudCBga2V5YCwgd2hpY2ggaXMgYSBjYWxsYWJsZSB3aGlj
aCByZXR1cm5zIGEgc3Vycm9nYXRlIHZhbHVlIHRvIGNvbXBhcmUsIGUuZy4gYSB0dXBsZSBvZiB0
aGUgZmllbGRzIHRvIGNvbXBhcmUsIG9yIGEgcHJveHkgb2JqZWN0IHdob3NlIGNvbXBhcmlzb24g
bWV0aG9kcyB5aWVsZCB0aGUgY3VycmVudCBvcmRlcmluZyBvZiBpbnRlcmVzdC7CoDxkaXY+PGJy
PjwvZGl2PjxkaXY+UHl0aG9uIDIgYWxzbyBvZmZlcnMgYSBgY21wYCBvcHRpb25hbCwgd2hpY2gg
aXMgYW5hbG9nb3VzIHRvIHRoZSBmdW5jdGlvbiBwYXNzZWQgdG8gQydzIGBxdWlja3NvcnRgLCBh
IGNhbGxhYmxlIHdoaWNoIGRlY2lkZXMgd2hpY2ggb2JqZWN0IGlzIGxhcmdlciwgYW5kIHJldHVy
bnMgLTEsIDAsIG9yIDEgdG8gaW5kaWNhdGUgd2hpY2guIFRoaXMgd2FzIHJlbW92ZWQgaW4gUHl0
aG9uIDMsIGJ1dCBgZnVuY3Rvb2xzLmNtcF90b19rZXlgIGNhbiBjb252ZXJ0IGEgY2FsbGFibGUg
dGhhdCBiZWhhdmVzIGxpa2UgYGNtcGAgaW50byBvbmUgdGhhdCBqdXN0IHJldHVybnMgc3Vycm9n
YXRlIHZhbHVlcyB0aGF0IHNhdGlzZnkgaXRzIHJlcXVpcmVtZW50cywgbWFraW5nIGl0IGNvbXBh
dGlibGUgd2l0aCB0aGUgYGtleWAgYXJndW1lbnQgdG8gdGhvc2Ugc29ydGluZyBtZXRob2RzLjwv
ZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY+VGhhdCBzYWlkLCBzb3J0aW5nIGludGVydmFscyBpcyBh
cHBsaWNhdGlvbiBzcGVjaWZpYywgc2luY2UgaXQgcmVhbGx5IGRlcGVuZHMgdXBvbiB3aGF0IHlv
dSdyZSBkb2luZyB3aXRoIHNhaWQgaW50ZXJ2YWxzLiBBbiBJbnRlcnZhbCBUcmVlIG9yIFNlZ21l
bnQgVHJlZSBkYXRhIHN0cnVjdHVyZSB3b3VsZCBiZSBhcHByb3ByaWF0ZSBmb3IgZmFzdCB0ZXN0
aW5nIGZvciBpbnRlcnZhbCBvdmVybGFwL3BvaW50IGluY2x1c2lvbiB0ZXN0cy4gRm9yIG90aGVy
IHByb2JsZW1zLCB5b3UgbWlnaHQgbmVlZCBtb3JlIG1ldGFkYXRhIHdoZW4gZXZhbHVhdGluZyBp
bnRlcnZhbCBxdWVyaWVzLCByZXF1aXJpbmcgc29tZXRoaW5nIG1vcmUgdGFpbG9yZWQuIEkndmUg
YXR0YWNoZWQgYW4gSW50ZXJ2YWwgVHJlZSBpbXBsZW1lbnRhdGlvbiBJIHVzZSB0aGF0IG1pZ2h0
IGJlIHVzZWZ1bCBmb3IgeW91IHRvby48L2Rpdj4=" style="height:0;width:0;max-height:0;max-width:0;overflow:hidden;font-size:0em;padding:0;margin:0">​</div></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Jan 31, 2017 at 9:41 AM, Peter Cock <span dir="ltr"><<a href="mailto:p.j.a.cock@googlemail.com" target="_blank">p.j.a.cock@googlemail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On Tue, Jan 31, 2017 at 2:31 PM, Chevreux, Bastien<br>
<<a href="mailto:bastien.chevreux@dsm.com">bastien.chevreux@dsm.com</a>> wrote:<br>
>> From: Joshua Klein [mailto:<a href="mailto:mobiusklein@gmail.com">mobiusklein@gmail.com</a>]<br>
><br>
>> […] When assigning to the class itself, not the module, the new<br>
>> comparator function is called<br>
><br>
> Yay, that worked, learning something new every day. Thanks a million.<br>
<br>
</span>Well spotted - I missed that.<br>
<span class=""><br>
> Peter: the ultimate goal of that request was to be able to call sort() on<br>
> features, with sometimes different and very custom sort criteria. Nothing<br>
> which would fit BioPython really.<br>
<br>
</span>I think sorting of local feature locations is semi-doable, something along<br>
the lines of sorting by int(start), int(end), and then strand. Feature<br>
locations which reference another accession would be troublesome,<br>
which is one reason I've not pushed ahead with this idea.<br>
<span class="HOEnZb"><font color="#888888"><br>
Peter<br>
</font></span></blockquote></div><br></div>