Home>

There is a list: [1, 3, 5, 'adf', 34, (1, 5, 8)] . I want to sort it by content type, so that integers, a string, and a tuple at the end.

That is, get the output: [1, 3, 5, 34, 'adf', (1, 5, 8)] .

How to achieve this?

Write your own comparator, where you will compare the types of elements. Or a good example.

entithat2021-04-17 22:00:23
  • Answer # 1

    Can be used sorting with its own comparatorand for it to set return values ​​as priority by type.

    Example:

    TYPE_BY_PRIORITY= {
        int: 0,
        str: 1,
        tuple: 2,
    }
    items= [1, 3, 5, 'adf', 34, (1, 5, 8)]
    items.sort (key= lambda x: TYPE_BY_PRIORITY.get (type (x)))
    print (items)
    # [1, 3, 5, 34, 'adf', (1, 5, 8)]
    

    UPD.

    For sorting without errors to handle types that are not in TYPE_BY_PRIORITY , then in .get you need to return the default value:

    items.sort (key= lambda x: TYPE_BY_PRIORITY.get (type (x), 99))
    

    UPD2.

    As suggested by MaxU , you can return a tuple of the form (priority, value) in the comparator, then sorting will be both by type and value (there will be an order for elements of the same type ):

    items.sort (key= lambda x: (TYPE_BY_PRIORITY.get (type (x), 99), x))
    

    This is noticeable with the sample [3, 1, 5, 'adf', 34, (1, 5, 8)] . A priority-only comparator will return [3, 1, 5, 34, 'adf', (1, 5, 8), 2.2] , and a priority-value comparator will return: [1, 3, 5, 34, 'adf', (1, 5, 8)]

    Nice, even hang on the wall)

    Alexander Chernin2021-04-17 22:00:23

    @AlexanderChernin, thanks :)

    gil9red2021-04-17 22:00:23

    You can use TYPE_BY_PRIORITY [type (x)] instead of get.

    insolor2021-04-17 22:00:23

    @insolor, it is better not to use it, because if a type unsupported in TYPE_BY_PRIORITY appears in the list, then the [] operator will throw a KeyError exception, and .get will return None in this case. Example: TYPE_BY_PRIORITY.get (type (2.3)) and TYPE_BY_PRIORITY [type (2.3)] :)

    gil9red2021-04-17 22:00:23

    @MaxU so that the same types are also ordered according to their meaning, yeah :) Thanks, I'll add this option :)

    gil9red2021-04-17 22:00:23
  • Answer # 2

    Python3 -15 bytes

    l.sort (key= dir)
    

    This is real code-golf.

    @insolor 15 bytes.

    Victor VosMottor2021-04-17 22:14:47
  • Answer # 3

    Here is a code-golf style solution. The l variable is your list:

    [x for x in l if isinstance (x, int)] + [i for i in l if isinstance (i, str)] + [j for j in l if isinstance (j, tuple)]
    

    Somehow long for code-golf. sum (map (lambda T: list (filter (lambda x: isinstance (x, T), L)), (int, str, tuple)), [])

    insolor2021-04-17 22:00:23

    @insolor Well, you're right, I meant it was pretty short and in one line. Of course your solution is better. Better write a separate answer.

    Victor VosMottor2021-04-17 22:00:23

    You may have succeeded in one line, but certainly not elegantly. I will not issue an answer, because the question is not about the shortest solution, but a normal solution has already been given by gil9red.

    insolor2021-04-17 22:00:23
  • Answer # 4

    Here's a "dirty hack" -by coincidence, it suits your case:

    a= [1, 3, 5, 'adf', 34, (1, 5, 8)]
    b= sorted (a, key= lambda x: str (type (x)))
    print (b)
    

    Result:

    [1, 3, 5, 34, 'adf', (1, 5, 8)]
    
  • Answer # 5

    A head-on solution:

    d= [1, 3, 5, 'adf', 34, (1, 5, 8)]
    digits= []
    strings= []
    tuples= []
    for i in d:
        if isinstance (i, str): # String?
            strings.append (i)
        elif isinstance (i, tuple): # Tuple?
            tuples.append (i)
        elif isinstance (i, int): # Number?
            digits.append (i)
    print (digits + strings + tuples)