Сортировка списка разделенных точками чисел, таких как версии программного обеспечения
У меня есть список, содержащий строки версии, например:
versions_list = ["1.1.2", "1.0.0", "1.3.3", "1.0.12", "1.0.2"]
Я хотел бы отсортировать его, поэтому результат будет примерно таким:
versions_list = ["1.0.0", "1.0.2", "1.0.12", "1.1.2", "1.3.3"]
Порядок приоритета цифр должен быть слева направо, и он должен опускаться. Поэтому 1.2.3
предшествует 2.2.3
и 2.2.2
предшествует 2.2.3
.
Как это сделать в Python?
Ответы
Ответ 1
Разделите каждую строку версии, чтобы сравнить ее как список целых чисел:
versions_list.sort(key=lambda s: map(int, s.split('.')))
Дает для вашего списка:
['1.0.0', '1.0.2', '1.0.12', '1.1.2', '1.3.3']
В Python3 map
больше не возвращается list
, поэтому нам нужно обернуть его в вызов list
.
versions_list.sort(key=lambda s: list(map(int, s.split('.'))))
Альтернативой карте является понимание списка. Подробнее см. этот пост.
versions_list.sort(key=lambda s: [int(u) for u in s.split('.')])
Ответ 2
Вы также можете использовать модуль distutils.version
стандартной библиотеки:
from distutils.version import StrictVersion
versions = ["1.1.2", "1.0.0", "1.3.3", "1.0.12", "1.0.2"]
versions.sort(key=StrictVersion)
Дает вам:
['1.0.0', '1.0.2', '1.0.12', '1.1.2', '1.3.3']
Он также может обрабатывать версии с тегами перед выпуском, например:
versions = ["1.1", "1.1b1", "1.1a1"]
versions.sort(key=StrictVersion)
Дает вам:
["1.1a1", "1.1b1", "1.1"]
Документация: https://github.com/python/cpython/blob/3.2/Lib/distutils/version.py#L101
Ответ 3
natsort предлагает "естественную сортировку"; который работает очень интуитивно (в Python 3)
from natsort import natsorted
versions = ["1.1.2", "1.0.0", "1.3.3", "1.0.12", "1.0.2"]
natsorted(versions)
дает
['1.0.0', '1.0.2', '1.0.12', '1.1.2', '1.3.3']
но он также работает с полными именами пакетов с номером версии:
versions = ['version-1.9', 'version-2.0', 'version-1.11', 'version-1.10']
natsorted(versions)
дает
['version-1.9', 'version-1.10', 'version-1.11', 'version-2.0']
Ответ 4
Я также решил этот вопрос, используя Python, хотя моя версия делает некоторые дополнительные вещи, вот мой код:
def answer(l):
list1 = [] # this is the list for the nested strings
for x in l:
list1.append(x.split("."))
list2 = [] # this is the same list as list one except everything is an integer in order for proper sorting
for y in list1:
y = map(int, y)
list2.append(y)
list3 = sorted(list2) #this is the sorted list of of list 2
FinalList = [] # this is the list that converts everything back to the way it was
for a in list3:
a = '.'.join(str(z) for z in a)
FinalList.append(a)
return FinalList
Для версий существуют три вещи; Майор, майор и пересмотр. Это делает так, что он организует его так, чтобы '1'
приходилось до '1.0'
, которое будет раньше '1.0.0'
. Кроме того, еще один плюс, не нужно импортировать библиотеки, если у вас их нет, и работает со старыми версиями Python, этот был специально предназначен для версии 2.7.6. Во всяком случае, вот несколько примеров:
Inputs:
(string list) l = ["1.1.2", "1.0", "1.3.3", "1.0.12", "1.0.2"]
Output:
(string list) ["1.0", "1.0.2", "1.0.12", "1.1.2", "1.3.3"]
Inputs:
(string list) l = ["1.11", "2.0.0", "1.2", "2", "0.1", "1.2.1", "1.1.1", "2.0"]
Output:
(string list) ["0.1", "1.1.1", "1.2", "1.2.1", "1.11", "2", "2.0", "2.0.0"]
Если у вас есть вопросы, просто прокомментируйте ответ!