Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to sort a mixed-typed list?

Tags:

python

I have a list that looks as follows (the 'None' in the list is a string, not a None):

profit = [1  , 20 , 3  , 5  , 90 , 'None', 900, 67 , 'None'] 
name   = ['a', 'b', 'c', 'e', 'd', 'f'   , 'g', 'k', 'pp']

The profit list is a list of "profit" values, so I had to sort it in a reversed order so that the highest values will be at the beginning.

Also, I have more lists with the same length that represent other things that are connected to the profit list (for example the name list that shows where the profit came from).

Now, I wrote the following code to sort the profit list in a reversed order, and I save the indices so I could sort the other lists (like name) according to the obtained indices:

sorted_ind = sorted(range(len(profit)), key=lambda k: profit[k], reverse=True)
for i in sorted_ind:
    print('{0:^50}|{1:^7}|'.format(profit[i], name[I]))

The above code works great when my profit list contains only numbers. However, there are cases where I have no profit and I would like this value to be 'None' (I don't want to set it to 0).

I'm trying to perform the same sort but in a way that all of the None indices will be at the end of the list - to sort all the ints and insert the Nones at the end.

Any good way to do it?

like image 370
Ben Avatar asked Jan 25 '23 04:01

Ben


1 Answers

You can use a "priority" key to the sort function which checks the types as well:

>>> sorted(profit, key=lambda x: (isinstance(x, int), x), reverse=True)
[900, 90, 67, 20, 5, 3, 1, 'None', 'None']

If you're doing that just to sort the names list, then it is not necessary to sort the indices, you should use zip:

profits = [1, 20, 3, 5, 90, 'None', 900, 67, 'None']
names = ['a', 'b', 'c', 'e', 'd', 'f', 'g', 'k', 'pp']

sorted_ind = sorted(zip(profits, names), key=lambda tup: (isinstance(tup[0], int), tup[0]), reverse=True)
for profit, name in sorted_ind:
    print('{0:^50}|{1:^7}|'.format(profit, name))

Gives:

                       900                        |   g   |
                        90                        |   d   |
                        67                        |   k   |
                        20                        |   b   |
                        5                         |   e   |
                        3                         |   c   |
                        1                         |   a   |
                       None                       |   f   |
                       None                       |  pp   |
like image 125
Tomerikoo Avatar answered Feb 05 '23 20:02

Tomerikoo