Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to sort tire sizes in python

I'm trying to sort list of (strings) tire sizes from smallest to biggest.

['285/30/18',
 '285/30/19',
 '235/40/17',
 '315/25/19',
 '275/30/19']

should be sort as:

['235/40/17',
 '285/30/18',
 '315/25/19'
 '275/30/19',
 '285/30/19']

I basically have to sort the strings starting from the right, middle then left.

What I have so far (bubble sort):

# this sorts the first numbers on the right.
nums = list(ulst)
for i in range(len(nums)):
     for j in range(i+1, len(nums)):
         if ulst[j].split('/')[2] < ulst[i].split('/')[2]:
             ulst[j], ulst[i] = ulst[i], ulst[j]

I now have to sort the middle without messing up the sorting on the right row, then sort the left row....

How do I solve this without creating a for/if nested mess?

like image 954
davierc Avatar asked Dec 11 '22 19:12

davierc


2 Answers

Python has several features that makes this easy to do. In fact, you can do it all in one statement:

sorted(nums, key=lambda x: tuple(reversed(list(map(int, x.split("/"))))))

The x.split("/") takes each value and makes a list of strings:

["235", "40", "17"]

Using map(int, ...) gives a list of integers:

[235, 40, 17]

reversed() turns that around:

[17, 40, 235]

and tuple() converts that into a tuple:

(17, 40, 235)

which, when compared to other similar tuples, gives the sorting order you want.

like image 91
Greg Hewgill Avatar answered Dec 30 '22 04:12

Greg Hewgill


One way is to construct the sort key using the following value function which takes into account the three fields in the correct order:

def value(s):
    arr = s.split('/')
    return arr[2] * 100000 + arr[1] * 1000 + arr[0]

ulst = ['285/30/18', '285/30/19', '235/40/17', '315/25/19', '275/30/19']

for i in range(len(ulst)):
     for j in range(i+1, len(ulst)):
         if value(ulst[j]) < value(ulst[i]):
             ulst[j], ulst[i] = ulst[i], ulst[j]

print ulst

The output of that is, as desired:

['235/40/17', '285/30/18', '315/25/19', '275/30/19', '285/30/19']

This will work fine provided that your tire sizes are 3/2/2 digits as specified which is a fairly safe bet - I've never seen a tyre below 12 inches and one of 100 inches would probably be too big to ride :-)

like image 33
paxdiablo Avatar answered Dec 30 '22 04:12

paxdiablo