2016-03-28 10 views
2

Zum Beispiel habe ich Listesortieren Liste der Zeichenfolge auf Nummer in String basierend

my_list= ['image101.jpg', 'image2.jpg', 'image1.jpg'] 

und

my_list.sort() 

gibt mir

['image1.jpg', 'image101.jpg', 'image2.jpg'] 

aber ich natürlich brauchen

['image1.jpg', 'image2.jpg', 'image101.jpg'] 

Wie kann es gemacht werden?

+1

'sortiert (my_list, key = lambda x: int (re.search (r '\ d + (= \.) ', x) .group())) ' –

Antwort

6

list.sort akzeptiert optionale key Funktion. Jedes Element wird an die Funktion übergeben, und der Rückgabewert der Funktion wird zum Vergleichen von Elementen anstelle der ursprünglichen Werte verwendet.

>>> my_list= ['image101.jpg', 'image2.jpg', 'image1.jpg'] 
>>> my_list.sort(key=lambda x: int(''.join(filter(str.isdigit, x)))) 
>>> my_list 
['image1.jpg', 'image2.jpg', 'image101.jpg'] 

filter wurden str.isdigit verwendete Nummern zu extrahieren:

>>> ''.join(filter(str.isdigit, 'image101.jpg')) 
'101' 
>>> int(''.join(filter(str.isdigit, 'image101.jpg'))) 
101 
  • ''.join(..) nicht in Python 2.x erforderlich
+2

Ich wollte nur erwähnen, dass es nicht funktioniert, wenn der Dateiname etwas wie' image21_20160328.jpg' ist. Die Nummer wird "2120160328" sein. – JRodDynamite

+0

@JasonEstibiro, Sie haben Recht.In diesem Fall müssen Sie alle Ziffern erfassen und konvertieren, indem Sie etwas wie lits (map (int, re.findall (r '\ d +', x))) – falsetru

6

Verwenden ein regulärer Ausdruck die Anzahl ziehen aus der Zeichenfolge und Cast zu Int:

import re 
r = re.compile("\d+") 
l = my_list= ['image101.jpg', 'image2.jpg', 'image1.jpg'] 
l.sort(key=lambda x: int(r.search(x).group())) 

Oder vielleicht eine spezifischere regex einschließlich der . verwenden:

import re 

r = re.compile("(\d+)\.") 
l = my_list= ['image101.jpg', 'image2.jpg', 'image1.jpg'] 
l.sort(key=lambda x: int(r.search(x).group())) 

beide die gleiche Ausgabe für Sie zB Eingang geben:

['image1.jpg', 'image2.jpg', 'image101.jpg'] 

Wenn Sie sicher, dass der Erweiterung sind Sie kann einen sehr spezifischen Regex verwenden:

r = re.compile("(\d+)\.jpg$") 
l.sort(key=lambda x: int(r.search(x).group(1))) 
+1

für die Genauigkeit verwenden, müssen Sie Lookahead verwenden. –

+4

Sie müssen die übereinstimmende Zeichenfolge in Nummer konvertieren. Ansonsten ist das Ergebnis anders als das, was OP will. '['bild1.jpg', 'bild101.jpg', 'bild2.jpg'] ! = ['bild1.jpg', 'bild2.jpg', 'bild101.jpg']' – falsetru

+0

@falsetru, yep, gepostet falsche Version ursprünglich –

2

Eigentlich brauchst du keine regex patern. Sie können leicht so parsen.

>>> 'image101.jpg'[5:-4] 
'101' 

Lösung:

>>> sorted(my_list, key=lambda x: int(x[5:-4])) 
['image1.jpg', 'image2.jpg', 'image101.jpg'] 
2

Wenn Sie dies im allgemeinen Fall tun wollen, würde ich ein natürliches Sortier Paket wie natsort versuchen.

from natsort import natsorted 
my_list = ['image101.jpg', 'image2.jpg', 'image1.jpg'] 
natsorted(my_list) 

Returns:

['image1.jpg', 'image2.jpg', 'image101.jpg'] 

Sie es installieren können mit pip dh pip install natsort

Verwandte Themen