Search code examples
pythonsortingcustomizationshort-circuiting

Python - How to make a custom (list) sort function with a 'short circuit' value (or flag)


I have a custom sort function similar to this question. However, I have one list value which - if present - must be sorted to the end of the list (to the last location). Is this possible to implement in a custom sort function?

I had considered the following:

mylist.sort(cust_sort)

def cust_sort(item1, item2):
    if item1.key == critical_value:
        #If the item1 in question is the "must be last" item, place it last.
        return -99 
        #There should never be more than 99 items in this list, but
        #   this number could be as large as necessary.
    if item1.key > item2.key:
        return 1
    elif item1.key < item2.key:
        return -1
    if item1.name > item2.name:
        return 0

    return 0

Note: I'd like to limit the scope of my implementation of this fix as much as possible - if possible to only this custom-sort function. I'm aware that I could remove this critical value, perform the sort, and re-add the critical value afterwards. However, this is legacy code and already quite confusing - implementing the fix directly in the custom sort function keeps influences outside of the operating scope to a minimum. I'd prefer to maximize readability and minimize disturbance.


Solution

  • Instead of creating a comparator function, create a key function:

    mylist.sort(key=lambda i: (i.key == CRITICAL_VALUE, i.key, i.name))
    

    This makes it clear (to me at least) that you first sort by i.key == CRITICAL_VALUE, then by i.key, and finally by i.name.