Ich habe einen Satz
set(['booklet', '4 sheets', '48 sheets', '12 sheets'])
Nach dem Sortieren soll es so aussehen
4 sheets,
12 sheets,
48 sheets,
booklet
Irgendeine Idee bitte
Antworten:
Kurz und bündig:
sorted(data, key=lambda item: (int(item.partition(' ')[0])
if item[0].isdigit() else float('inf'), item))
Diese Version:
cmp
Parameter to wird nicht verwendet sorted
(was in Python 3 nicht vorhanden ist).Wenn Sie eine Druckausgabe genau wie in Ihrem Beispiel beschrieben wünschen, dann:
data = set(['booklet', '4 sheets', '48 sheets', '12 sheets'])
r = sorted(data, key=lambda item: (int(item.partition(' ')[0])
if item[0].isdigit() else float('inf'), item))
print ',\n'.join(r)
Jeff Atwood spricht über natürliche Sorte und gibt ein Beispiel für eine Möglichkeit, dies in Python zu tun. Hier ist meine Variation davon:
import re
def sorted_nicely( l ):
""" Sort the given iterable in the way that humans expect."""
convert = lambda text: int(text) if text.isdigit() else text
alphanum_key = lambda key: [ convert(c) for c in re.split('([0-9]+)', key) ]
return sorted(l, key = alphanum_key)
Verwenden Sie wie folgt:
s = set(['booklet', '4 sheets', '48 sheets', '12 sheets'])
for x in sorted_nicely(s):
print(x)
Ausgabe:
4 sheets
12 sheets
48 sheets
booklet
Ein Vorteil dieser Methode ist, dass sie nicht nur funktioniert, wenn die Zeichenfolgen durch Leerzeichen getrennt sind. Es funktioniert auch für andere Trennzeichen, z. B. den Punkt in Versionsnummern (z. B. 1.9.1 steht vor 1.10.0).
[('b', 0), ('0', 1), ('a', 2)]
ist sortiert nach[('0', 1), ('a', 2), ('b', 0)]
.lower()
zu key
in re.split
.
Sie sollten die Natsortierung der Drittanbieter-Bibliothek überprüfen . Sein Algorithmus ist allgemein, so dass er für die meisten Eingaben funktioniert.
>>> import natsort
>>> your_list = set(['booklet', '4 sheets', '48 sheets', '12 sheets'])
>>> print ',\n'.join(natsort.natsorted(your_list))
4 sheets,
12 sheets,
48 sheets,
booklet
Eine einfache Möglichkeit besteht darin, die Zeichenfolgen in numerische und nicht numerische Teile aufzuteilen und die Zeichenfolgen mithilfe der Python-Tupel-Sortierreihenfolge zu sortieren.
import re
tokenize = re.compile(r'(\d+)|(\D+)').findall
def natural_sortkey(string):
return tuple(int(num) if num else alpha for num, alpha in tokenize(string))
sorted(my_set, key=natural_sortkey)
Es wurde vorgeschlagen, diese Antwort hier erneut zu veröffentlichen, da sie auch in diesem Fall gut funktioniert
from itertools import groupby
def keyfunc(s):
return [int(''.join(g)) if k else ''.join(g) for k, g in groupby(s, str.isdigit)]
sorted(my_list, key=keyfunc)
Demo:
>>> my_set = {'booklet', '4 sheets', '48 sheets', '12 sheets'}
>>> sorted(my_set, key=keyfunc)
['4 sheets', '12 sheets', '48 sheets', 'booklet']
Für Python3 muss es leicht geändert werden (diese Version funktioniert auch in Python2 einwandfrei).
def keyfunc(s):
return [int(''.join(g)) if k else ''.join(g) for k, g in groupby('\0'+s, str.isdigit)]
>>> a = set(['booklet', '4 sheets', '48 sheets', '12 sheets'])
>>> def ke(s):
i, sp, _ = s.partition(' ')
if i.isnumeric():
return int(i)
return float('inf')
>>> sorted(a, key=ke)
['4 sheets', '12 sheets', '48 sheets', 'booklet']
Allgemeine Antwort zum Sortieren beliebiger Zahlen an einer beliebigen Position in einem Array von Zeichenfolgen. Funktioniert mit Python 2 & 3.
def alphaNumOrder(string):
""" Returns all numbers on 5 digits to let sort the string with numeric order.
Ex: alphaNumOrder("a6b12.125") ==> "a00006b00012.00125"
"""
return ''.join([format(int(x), '05d') if x.isdigit()
else x for x in re.split(r'(\d+)', string)])
Stichprobe:
s = ['a10b20','a10b1','a3','b1b1','a06b03','a6b2','a6b2c10','a6b2c5']
s.sort(key=alphaNumOrder)
s ===> ['a3', 'a6b2', 'a6b2c5', 'a6b2c10', 'a06b03', 'a10b1', 'a10b20', 'b1b1']
Ein Teil der Antwort kommt von dort
Basierend auf der Antwort von SilentGhost:
In [4]: a = set(['booklet', '4 sheets', '48 sheets', '12 sheets'])
In [5]: def f(x):
...: num = x.split(None, 1)[0]
...: if num.isdigit():
...: return int(num)
...: return x
...:
In [6]: sorted(a, key=f)
Out[6]: ['4 sheets', '12 sheets', '48 sheets', 'booklet']
Sets sind von Natur aus ungeordnet. Sie müssen eine Liste mit demselben Inhalt erstellen und diese sortieren.
Für Leute, die mit einer Python-Version vor 2.4 ohne die wunderbare sorted()
Funktion stecken , ist eine schnelle Möglichkeit, Sets zu sortieren:
l = list(yourSet)
l.sort()
Dies beantwortet nicht die oben genannte spezifische Frage ( 12 sheets
wird vorher kommen 4 sheets
), kann jedoch für Personen von Google nützlich sein.
4a sheets
aber wen interessiert das? Um dies zu beheben, benötigen Sie eine echte Funktion anstelle eines Lambda.