2010-04-04 2 views
42

ich eine Liste mit Versionsstrings haben, wie Dinge:Sortieren einer Liste von durch Punkte getrennte Zahlen, wie Software-Versionen

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

Ich möchte es sortieren, so dass das Ergebnis etwas so sein würde:

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

Die Rangfolge für die Ziffern sollte offensichtlich von links nach rechts sein, und es sollte absteigend sein. So kommt 1.2.3 vor 2.2.3 und 2.2.2 kommt vor 2.2.3.

Wie mache ich das in Python?

+0

Ähnliche [Wie man "version-style" Zeichenfolgen vergleicht] (http://stackoverflow.com/q/11887762) –

Antwort

61

Split jede Version Zeichenkette, die es als eine Liste von ganzen Zahlen vergleichen:

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

gibt, für die Liste:

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

In Python3 map nicht mehr list zurückgibt, also müssen wir wrap it in a list call.

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

Die Alternative zur Abbildung hier ist ein list comprehension. Siehe this post für weitere Listenkompromittierungen.

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

Für die reguläre Ausdruck Lösung würden Sie nur die s mit dem Ausdruck ersetzen, die die gewünschte Gruppe zurückgibt . Zum Beispiel: Lambda s: Karte (int, re.search (myre, s). Gruppen [0] .split ('.')) –

+0

Vielen Dank, arbeitete wie ein Charme – Zack

+2

Das ist pure Eleganz. –

87

Sie auch distutils.version Modul der Standardbibliothek verwenden:

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) 

Geben Sie:

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

Es ist auch Pre-Release-Versionen mit Tags, beispielsweise umgehen kann:

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

Gibt Ihnen:

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

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

+3

+1. Cool. Ich würde diese Lösung bevorzugen. –

+1

Scheint mehr pythonisch als Elis Lösung. –

+13

Es gibt auch distutils.version.LooseVersion, die mit Versionsnummern, die in Buchstaben enden ('1.0b', '1.0.2-final'), usw., oder was auch immer - ich bevorzuge diese Version, da StrictVersion zu sein scheint Die LooseVersion orientiert sich mehr an Python Distutils spezifischen Versions-Strings, LoserVersion bietet eine breite Palette möglicher Versions-Strings, die Sie in der freien Wildbahn sehen können. – synthesizerpatel

5

natsort schlägt "natürliche Sortierung"; Weiche funktioniert sehr intuitiv (in 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'] 

aber es funktioniert auch auf kompletten Paketnamen mit der Versionsnummer gibt:

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

gibt

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

Ihr Beispiel funktioniert nicht: 'natsort (Versionen)': 'TypeError: 'Modul' Objekt ist nicht aufrufbar ' –

+0

Sie sollten Python 3 verwenden ... –

+0

Ich benutze nur Python3.4 –

1

habe ich auch th gelöst mein Code Frage Python verwenden, obwohl meine Version einige zusätzliche Dinge tut, ist hier:

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 

Für Versionen gibt es drei Dinge; Major, Minor und die Überarbeitung. Was dies tut ist, dass es es organisiert, so dass '1' vor '1.0' kommt, die vor '1.0.0' kommen wird. Ein weiterer Pluspunkt ist, dass Sie keine Bibliotheken importieren müssen, wenn Sie sie nicht haben, und es funktioniert mit alten Versionen von Python, die speziell für Version 2.7.6 gedacht waren. Wie auch immer, hier sind ein paar Beispiele:

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

Wenn Sie Fragen haben, kommentieren Sie einfach die Antwort !!

Verwandte Themen