2010-04-04 10 views
42

Ho una lista che contiene stringhe di versione, come ad esempio le cose:Ordinamento di un elenco di numeri separati da punti, come le versioni software

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

Vorrei ordinare, quindi il risultato sarebbe qualcosa di simile a questo:

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

L'ordine di precedenza per le cifre deve essere ovviamente da sinistra a destra e deve essere decrescente. Quindi 1.2.3 arriva prima dello 2.2.3 e 2.2.2 prima dello 2.2.3.

Come posso farlo in Python?

+0

Correlati [Come confrontare le stringhe "version-style"] (http://stackoverflow.com/q/11887762) –

risposta

61

Split ogni stringa di versione per confrontare come una lista di interi:

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

Dà, per la vostra lista:

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

In python3 map non restituisce più un list, quindi abbiamo bisogno di wrap it in a list call.

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

L'alternativa alla mappa è list comprehension. Vedi this post per ulteriori informazioni sulla comprensione delle liste.

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

Per la soluzione di espressioni regolari si dovrebbe semplicemente sostituire la s con l'espressione che restituisce il gruppo che si desidera . Ad esempio: lambda s: map (int, re.search (myre, s) .groups [0] .split ('.')) –

+0

Grazie, ha funzionato come un fascino – Zack

+2

Questa è pura eleganza. –

87

È anche possibile utilizzare distutils.version modulo della libreria standard:

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) 

Ti dà:

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

Si può anche gestire versioni con tag pre-release, ad esempio:

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

si ottiene:

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

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

+3

+1. Freddo. Preferirei questa soluzione. –

+1

Sembra più pitone della soluzione di Eli. –

+13

C'è anche distutils.version.LooseVersion che è un po 'più indulgente con i numeri di versione che terminano con lettere [' 1.0b ',' 1.0.2-final '], ecc. O quant'altro - Preferisco questa versione dal momento che StrictVersion sembra essere più orientato verso le distutils della versione specifica di Python, LooseVersion si rivolge a una gamma più ampia di potenziali stringhe di versione che vedrai in natura. – synthesizerpatel

5

natsort propone "ordinamento naturale"; Quale funziona molto intuitivamente (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'] 

ma funziona così sui nomi dei pacchetti completi di numero di versione:

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'] 
+0

Il tuo esempio non funziona: 'natsort (versions)': 'TypeError: 'module' object is not callable' –

+0

Dovresti usare python 3 ... –

+0

Io uso solo python3.4 –

1

Ho anche risolto è domanda utilizzando Python, anche se la mia versione fa alcune cose in più, qui è il mio codice:

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 

Per le versioni esistono tre cose; Maggiore, minore e revisione. Ciò che fa è che lo organizza in modo che '1' arriverà prima dello '1.0' che verrà prima dello '1.0.0'. Inoltre, un altro vantaggio, non c'è bisogno di importare alcuna libreria nel caso in cui non ce l'hai, e funziona con le vecchie versioni di Python, questo era specificamente pensato per la versione 2.7.6. Comunque, ecco alcuni esempi:

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

Se avete domande, basta commentare la risposta !!

Problemi correlati