2010-04-04 9 views
42

Mam listę zawierającą ciągi wersji, takie jak rzeczy:Sortowanie listę liczb oddzielonych kropkami, jak wersje oprogramowania

versions_list = ["1.1.2", "1.0.0", "1.3.3", "1.0.12", "1.0.2"] 

chciałbym go rozwiązać, więc wynik będzie coś takiego:

versions_list = ["1.0.0", "1.0.2", "1.0.12", "1.1.2", "1.3.3"] 

Kolejność pierwszeństwa cyfr powinna oczywiście być od lewej do prawej i powinna być opadająca. Tak więc 1.2.3 pojawia się przed 2.2.3 i 2.2.2 przed 2.2.3.

Jak to zrobić w języku Python?

+0

Powiązane artykuły [Jak porównać ciągi znaków "styl wersji"] (http://stackoverflow.com/q/11887762) –

Odpowiedz

61

Split każdy ciąg wersja porównać go jako lista liczb całkowitych:

versions_list.sort(key=lambda s: map(int, s.split('.'))) 

daje na liście:

['1.0.0', '1.0.2', '1.0.12', '1.1.2', '1.3.3'] 

W Python3 map nie zwraca list, więc musimy wrap it in a list call.

versions_list.sort(key=lambda s: list(map(int, s.split('.')))) 

Alternatywą dla mapy tutaj jest list comprehension. Zobacz this post, aby uzyskać więcej informacji na temat sprawdzania listy.

versions_list.sort(key=lambda s: [int(u) for u in s.split('.')]) 
+0

W przypadku wyrażenia regularnego wystarczy zastąpić s wyrażeniem zwracającym żądaną grupę . Na przykład: lambda s: map (int, re.search (myre, s) .groups [0] .split ('.')) –

+0

Dziękuję, zadziałało jak wdzięk – Zack

+2

To jest czysta elegancja. –

87

Można również użyć distutils.version moduł biblioteki standardowej:

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) 

Daje:

['1.0.0', '1.0.2', '1.0.12', '1.1.2', '1.3.3'] 

Może również obsługiwać wersje z tagami przedpremierowych, na przykład:

versions = ["1.1", "1.1b1", "1.1a1"] 
versions.sort(key=StrictVersion) 

Daje:

["1.1a1", "1.1b1", "1.1"] 

Dokumentacja: https://github.com/python/cpython/blob/3.2/Lib/distutils/version.py#L101

+3

+1. Chłodny. Wolałbym to rozwiązanie. –

+1

Wydaje się, że bardziej pythonic niż rozwiązanie Eli. –

+13

Istnieje również distutils.version.LooseVersion, który jest nieco bardziej wybaczający z numerami wersji, które kończą się literami ['1.0b', '1.0.2-final'] itp. Lub czymkolwiek - ja wolę tę wersję, ponieważ wydaje się, że StrictVersion jest bardziej ukierunkowane na specyficzne łańcuchy wersji Python distutils, LooseVersion kieruje się do szerszego zakresu potencjalnych ciągów wersji, które zobaczysz na wolności. – synthesizerpatel

5

natsort proponuje "naturalne sortowania"; wich działa bardzo intuicyjnie (w Pythonie 3)

from natsort import natsorted 
versions = ["1.1.2", "1.0.0", "1.3.3", "1.0.12", "1.0.2"] 
natsorted(versions) 

daje

['1.0.0', '1.0.2', '1.0.12', '1.1.2', '1.3.3'] 

ale działa także na pełnych nazw pakietów z numerem wersji:

versions = ['version-1.9', 'version-2.0', 'version-1.11', 'version-1.10'] 
natsorted(versions) 

daje

['version-1.9', 'version-1.10', 'version-1.11', 'version-2.0'] 
+0

Twój przykład nie działa: 'natsort (wersje)': TypeError ': 'moduł' obiekt nie jest callable' –

+0

Należy używać Python 3 ... –

+0

używam tylko python3.4 –

1

Rozwiązałem również jest pytanie za pomocą Python, chociaż moja wersja robi kilka dodatkowych rzeczy, oto mój kod:

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 

Dla wersji istnieją trzy rzeczy; Major, Minor i rewizja. Dzieje się tak dlatego, że organizuje to tak, aby '1' pojawiło się przed '1.0', co nastąpi przed '1.0.0'. Kolejny plus, nie ma potrzeby importowania żadnych bibliotek, ale nie masz ich i działa ze starszymi wersjami Pythona, ten był przeznaczony specjalnie dla wersji 2.7.6. W każdym razie, oto kilka przykładów:

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"] 

Jeśli masz jakieś pytania, po prostu skomentuj odpowiedź !!

Powiązane problemy