Python Forum

Full Version: sorting
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2 3
The lambda would look like this as a full function:

def sort_order(item):
    if isinstance(item, (int, float)):
        index = 0
    else:
        index = 1
    return (index, item)
You could simplify that some, but I'm trying to be clear. As zivoni points out, you can expand that:


def sort_order(item):
    if isinstance(item, (int, float)):
        index = 0
    elif isinstance(item, str):
        index = 1
    elif isinstance(item, (tuple, list)):
        index = 2
    elif isinstance(item, (dict, set)):
        index = 3
    else:
        index = 99
    return (index, item)
And of course, any big if/elif/else structure suggests a dictionary:

type_order = {int: 0, float: 0, str: 1, list: 2, tuple: 2, dict: 3, set: 3}
mixed_list.sort(key = lambda x: (type_order.get(x, 99), x))
That key lambda could be rewritten as:
def key_tuple(x):
    if isinstance(x, (int, float)):
        return (0, x)
    return (1, str(x))
And how it works:
Output:
>>> data = [1, "a string", 5, 2.718, "eleven", 11, (3, 2, 1)] # keys for list data are: >>> list(map(key_tuple, data)) [(0, 1), (1, 'a string'), (0, 5), (0, 2.718), (1, 'eleven'), (0, 11), (1, '(3, 2, 1)')] # and they are sorted in this order: >>> sorted(map(key_tuple, data)) [(0, 1), (0, 2.718), (0, 5), (0, 11), (1, '(3, 2, 1)'), (1, 'a string'), (1, 'eleven')] # so original list will be sorted this way: >>> sorted(data, key=key_tuple) [1, 2.718, 5, 11, (3, 2, 1), 'a string', 'eleven']
Basically it works like your split / sort / join approach if you consider everything with key (0, ..) as a first  "group"  and everything with key(1, ...) as a second "group". As (0, ...) < (1, ...) lexicographically (regardless of elements  on 2nd position), everything in a first group will be before any item from a second group. And inside groups (tie breaking) items are sorted by second element of tuple, so for numbers naturally as a number, for other types as strings with str().
Thanks! I think it's clear now.
(Mar-18-2017, 10:23 AM)wavic Wrote: [ -> ]I still don't get it. Can you convert lambda x: (0, x) if isinstance(x, (int, float)) else (1, str(x))) to a normal function, please

def sortkey(x):
    return (0,x) if isinstance(x, (int, float)) else (1, str(x))
Or in slow-motion:

def sortkey(x):
    if isinstance(x,int) or instance(x,float): 
        return (0,x) 
    else:
        return (1, str(x))
Pages: 1 2 3