Duplicate possible:
Est-ce que Python possède une fonction intégrée pour le tri naturel des chaînes?
J'ai une liste de chaînes contenant des nombres et je ne trouve pas un bon moyen de les trier.
Par exemple, je reçois quelque chose comme ceci:
something1
something12
something17
something2
something25
something29
avec la méthode sort()
.
Je sais que j'ai probablement besoin d'extraire les chiffres d'une manière ou d'une autre et ensuite de trier la liste, mais je ne sais pas comment le faire de la manière la plus simple.
Peut-être recherchez-vous tri humain (aussi appelé tri naturel ):
import re
def atoi(text):
return int(text) if text.isdigit() else text
def natural_keys(text):
'''
alist.sort(key=natural_keys) sorts in human order
http://nedbatchelder.com/blog/200712/human_sorting.html
(See Toothy's implementation in the comments)
'''
return [ atoi(c) for c in re.split(r'(\d+)', text) ]
alist=[
"something1",
"something12",
"something17",
"something2",
"something25",
"something29"]
alist.sort(key=natural_keys)
print(alist)
les rendements
['something1', 'something2', 'something12', 'something17', 'something25', 'something29']
PS J'ai changé ma réponse pour utiliser la mise en œuvre du tri naturel de Toothy (posté dans les commentaires ici ) car il est nettement plus rapide que ma réponse d'origine.
Si vous souhaitez trier le texte avec des flottants, vous devez changer la regex de celle qui correspond à ints (i.e. (\d+)
) à ne expression rationnelle qui correspond à float :
import re
def atof(text):
try:
retval = float(text)
except ValueError:
retval = text
return retval
def natural_keys(text):
'''
alist.sort(key=natural_keys) sorts in human order
http://nedbatchelder.com/blog/200712/human_sorting.html
(See Toothy's implementation in the comments)
float regex comes from https://stackoverflow.com/a/12643073/190597
'''
return [ atof(c) for c in re.split(r'[+-]?([0-9]+(?:[.][0-9]*)?|[.][0-9]+)', text) ]
alist=[
"something1",
"something2",
"something1.0",
"something1.25",
"something1.105"]
alist.sort(key=natural_keys)
print(alist)
les rendements
['something1', 'something1.0', 'something1.105', 'something1.25', 'something2']