0

I have a list of semantic code versions and I would like to sort it based on semver. Here is an example where the default sort is incorrect:

['0.0.1', '0.0.2', '0.1.0', '0.10.0', '0.11.0', '0.12.0', '0.13.0', '0.13.1', '0.13.2', '0.14.0', '0.15.0', '0.16.0', '0.17.0', '0.18.0', '0.19.0', '0.2.0']

'0.2.0' should come before '0.10.0'. I know there are semantic libraries but didn't see any examples of how to sort with them, rather they check for validity of the semantic version.

Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
rchitect-of-info
  • 1,150
  • 1
  • 11
  • 23
  • Sorry, correct dup: [Sorting a list of dot-separated numbers, like software versions](https://stackoverflow.com/questions/2574080/sorting-a-list-of-dot-separated-numbers-like-software-versions) – Tomerikoo Dec 15 '20 at 18:52
  • Thanks @Tomerikoo for the link, that did not come up on the first few pages when I searched previously. It does work as-is, thx! – rchitect-of-info Dec 15 '20 at 18:55

2 Answers2

5

The following code should do the job:

a = ['0.0.1', '0.0.2', '0.1.0', '0.10.0', '0.11.0', '0.12.0', '0.13.0', '0.13.1', '0.13.2', '0.14.0', '0.15.0', '0.16.0', '0.17.0', '0.18.0', '0.19.0', '0.2.0']

a.sort(key = lambda x: [int(y) for y in x.split('.')])

print(a)

See the result:

['0.0.1', '0.0.2', '0.1.0', '0.2.0', '0.10.0', '0.11.0', '0.12.0', '0.13.0', '0.13.1', '0.13.2', '0.14.0', '0.15.0', '0.16.0', '0.17.0', '0.18.0', '0.19.0']

It works even if the list contains '0.12.0.1':

b = ['0.12.0.1', '0.0.1', '0.0.2', '0.1.0', '0.10.0', '0.11.0', '0.12.0', '0.13.0', '0.13.1', '0.13.2', '0.14.0', '0.15.0', '0.16.0', '0.17.0', '0.18.0', '0.19.0', '0.2.0']

b.sort(key = lambda x: [int(y) for y in x.split('.')])

print(b)

Here is the result:

['0.0.1', '0.0.2', '0.1.0', '0.2.0', '0.10.0', '0.11.0', '0.12.0', '0.12.0.1', '0.13.0', '0.13.1', '0.13.2', '0.14.0', '0.15.0', '0.16.0', '0.17.0', '0.18.0', '0.19.0']
modnar
  • 274
  • 1
  • 6
0

Tuples compare from left to right, so split each element into a tuple of ints and use that as a key:

l = ['0.0.1', '0.0.2', '0.1.0', '0.10.0', '0.11.0', '0.12.0', '0.13.0', '0.13.1', '0.13.2', '0.14.0', '0.15.0', '0.16.0', '0.17.0', '0.18.0', '0.19.0', '0.2.0']
print(sorted(l, key=lambda version: tuple(int(n) for n in verion.split("."))))
# ['0.0.1', '0.0.2', '0.1.0', '0.2.0', '0.10.0', '0.11.0', '0.12.0', '0.13.0', '0.13.1', '0.13.2', '0.14.0', '0.15.0', '0.16.0', '0.17.0', '0.18.0', '0.19.0']
Roy Cohen
  • 1,540
  • 1
  • 5
  • 22
Aplet123
  • 33,825
  • 1
  • 29
  • 55