2010-04-04 21 views
42

Tengo una lista que contiene cadenas de versión, como las cosas:Ordenar una lista de números separados por puntos, al igual que las versiones de software

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

me gustaría resolverlo, por lo que el resultado sería algo como esto:

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

El orden de precedencia de los dígitos, obviamente, debe ser de izquierda a derecha, y debe ser descendente. Entonces 1.2.3 viene antes de 2.2.3 y 2.2.2 viene antes de 2.2.3.

¿Cómo hago esto en Python?

+0

Relacionados [Cómo comparar cadenas de "estilo de versión"] (http://stackoverflow.com/q/11887762) –

Respuesta

61

Dividir cada cadena de versión para compararlo como una lista de números enteros:

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

da, para su lista:

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

En python3 map ya no devuelve un list, por lo que necesitamos wrap it in a list call.

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

La alternativa para hacer el mapa aquí es list comprehension. Consulte this post para obtener más información sobre la lista de comprensiones.

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

Para la solución de expresión regular, simplemente reemplazaría la s con la expresión que devuelve el grupo que desea . Por ejemplo: lambda s: map (int, re.search (myre, s) .groups [0] .split ('.')) –

+0

Gracias, trabajado como un encanto – Zack

+2

Esto es pura elegancia. –

87

También puede utilizar distutils.version módulo de la biblioteca estándar:

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) 

le ofrece:

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

También puede manejar las versiones con etiquetas pre-lanzamiento, por ejemplo:

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

le ofrece:

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

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

+3

+1. Guay. Preferiría esta solución. –

+1

Parece más pitónico que la solución de Eli. –

+13

También hay distutils.version.LooseVersion que es un poco más tolerante con los números de versión que terminan en letras ['1.0b', '1.0.2-final'], etc. o lo que sea, prefiero esta versión ya que StrictVersion parece ser más orientado hacia Python distutils cadenas de versión específica, LooseVersion atiende a una amplia gama de cadenas de versión potencial que verá en la naturaleza. – synthesizerpatel

5

natsort propone "clasificación natural"; wich funciona muy intuitiva (en Python 3)

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

da

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

pero funciona tan bien en los nombres de paquetes completos con número de versión:

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

da

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

Su ejemplo no funciona: 'natsort (versions)': 'TypeError: 'module' object no se puede llamar' –

+0

Debería usar python 3 ... –

+0

Uso solo python3.4 –

1

También resolví th es cuestión usando Python, aunque mi versión hace algunas cosas de más, aquí está mi código:

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 

Para versiones existen tres cosas; Mayor, menor y la revisión. Lo que hace esto es que lo organiza de modo que '1' vendrá antes del '1.0' que vendrá antes del '1.0.0'. Además, otra ventaja, no es necesario importar ninguna biblioteca en el caso de que no la tenga, y funciona con las versiones anteriores de Python, esta fue específicamente diseñada para la Versión 2.7.6. De todos modos, aquí hay algunos ejemplos:

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

¡Si tiene alguna pregunta, solo comente la respuesta!

Cuestiones relacionadas