So I have a list of version numbers, eg:
["1.11", "2.0.0", "1.2", "2", "0.1", "1.2.1", "1.1.1", "2.0"]
and I want to order them from smallest to largest. I found that I can use the sorted()
function, and that orders it well. Here's the function I came up with:
def order(l):
# Sorts numbers from smallest to largest
orderedList = sorted(l)
strList = ""
for i in range(len(orderedList)):
strList = orderedList[i]
# Don't put a comma for the last loop
if i < len(orderedList) - 1:
strList = ", "
print(strList)
So,
order(["1.11", "2.0.0", "1.2", "2", "0.1", "1.2.1", "1.1.1", "2.0"])
currently outputs:
0.1, 1.1.1, 1.11, 1.2, 1.2.1, 2, 2.0, 2.0.0
.
This may look right, but I need it to order differently.
My desired output is:
0.1, 1.1.1, 1.2, 1.2.1, 1.11, 2, 2.0, 2.0.0
In other words, I need to tell the program that 1.11
is like one.eleven
, not a decimal one.oneone
, and is therefore bigger than 1.2
or 1.2.1
. Similar to Minecraft's versioning system; 1.18
is bigger than 1.8.9
, and I need the function to order the program like that. But the sorted()
function orders it so that 1.8.9
is bigger than 1.18
Is there an obvious solution that I've missed?
Is it more complicated than I anticipated?
Do I need to create my own ordering function as an alternative to sorted()
?
Could I somehow use the key parameter in sorted
to construct my own order? If so, how?
Thanks in advance
CodePudding user response:
You want to sort such that each number in that version is compared to another one in the same position as an int
eger, so just split by dot, map to int
, cast to tuple
for the sorting key, then you can join
that list and avoid using that for
loop you have there:
def order(lst):
lst = sorted(lst, key=lambda x: tuple(map(int, x.split("."))))
return ", ".join(lst)
print(order(["1.11", "2.0.0", "1.2", "2", "0.1", "1.2.1", "1.1.1", "2.0"]))
# 0.1, 1.1.1, 1.2, 1.2.1, 1.11, 2, 2.0, 2.0.0
CodePudding user response:
What you're looking for is really called human sort. And there is a lib for that purpose:
You just have to pip install natsort
first to get the lib. Why do we need to reinvent the wheel instead of focus solving our real problem?
import natsort
ans = natsort.natsorted(lst)
ans
['0.1', '1.1.1', '1.2', '1.2.1', '1.11', '2', '2.0', '2.0.0']
another example
heights = '125 inches,11 inches,25 inches,2 inches,100 inches'
sort_heights = natsort.natsorted(heights.split(','))
sort_heights
['2 inches', '11 inches', '25 inches', '100 inches', '125 inches']