J'ai un set
set(['booklet', '4 sheets', '48 sheets', '12 sheets'])
Après le tri, je veux que ça ressemble à
4 sheets,
12 sheets,
48 sheets,
booklet
Toute idée s'il vous plaît
Court et doux:
sorted(data, key=lambda item: (int(item.partition(' ')[0])
if item[0].isdigit() else float('inf'), item))
Cette version:
cmp
à sorted
(qui n'existe pas dans Python 3)Si vous voulez une sortie imprimée exactement comme décrit dans votre exemple, alors:
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 parle de type naturel et donne un exemple d'une façon de le faire en Python. Voici ma variation à ce sujet:
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)
Utilisez comme ceci:
s = set(['booklet', '4 sheets', '48 sheets', '12 sheets'])
for x in sorted_nicely(s):
print(x)
Sortie:
4 sheets
12 sheets
48 sheets
booklet
Un des avantages de cette méthode est qu’elle ne fonctionne pas uniquement lorsque les chaînes sont séparées par des espaces. Cela fonctionnera également pour d'autres séparateurs tels que la période dans les numéros de version (par exemple, 1.9.1 est antérieure à 1.10.0).
Vous devriez vérifier la bibliothèque tierce partie natsort . Son algorithme est général donc il fonctionnera pour la plupart des entrées.
>>> 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
Un moyen simple consiste à scinder les chaînes en parties numériques et en parties non numériques et à utiliser l'ordre de tri Tuple python pour trier les chaînes.
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)
Il a été suggéré que je republie cette réponse ici car cela fonctionne bien pour ce cas aussi
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)
Démo:
>>> my_set = {'booklet', '4 sheets', '48 sheets', '12 sheets'}
>>> sorted(my_set, key=keyfunc)
['4 sheets', '12 sheets', '48 sheets', 'booklet']
Pour Python3, il est nécessaire de le modifier légèrement (cette version fonctionne aussi bien en Python2)
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']
Basé sur la réponse de 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']
les ensembles sont intrinsèquement non commandés. Vous devrez créer une liste avec le même contenu et le trier.
Réponse générique pour trier tous les nombres à n’importe quelle position dans un tableau de chaînes. Fonctionne avec 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)])
Échantillon:
s = ['a10b20','a10b1','a3','b1b1','a06b03','a6b2','a6b2c10','a6b2c5']
s.sort(key=alphaNumOrder)
s ===> ['a3', 'a6b2', 'a6b2c5', 'a6b2c10', 'a06b03', 'a10b1', 'a10b20', 'b1b1']
Une partie de la réponse est à partir de là
Pour les personnes coincées avec une version de Python antérieure à la 2.4, sans la fonction sorted()
merveilleuse, un moyen rapide de trier les ensembles est:
l = list(yourSet)
l.sort()
Cela ne répond pas à la question spécifique ci-dessus (12 sheets
viendra avant 4 sheets
), mais cela pourrait être utile aux personnes venant de Google.