Подтвердить что ты не робот

Сортировка списка разделенных точками чисел, таких как версии программного обеспечения

У меня есть список, содержащий строки версии, например:

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?

4b9b3361

Ответ 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"]

Если у вас есть вопросы, просто прокомментируйте ответ!