2011-03-30 8 views
8

si j'ai une liste de chaînes par ex. ["a143.txt", "a9.txt", ] comment puis-je le trier dans l'ordre croissant par les nombres dans la liste, plutôt que par la chaîne. C'est à dire. Je veux "a9.txt" apparaître avant "a143.txt" depuis 9 < 143.liste de tri en python

merci.

+2

Est-ce toujours le préfixe 'a'? – poke

+1

Cette question ne semble pas avoir de rapport avec 'scipy' ou' numpy'. Si c'est le cas, supprimez ces balises. – JoshAdel

+1

Étiquettes modifiées. Maintenant, c'est plus clair. –

Répondre

13

Il est appelé "ordre de tri naturel", De http://www.codinghorror.com/blog/2007/12/sorting-for-humans-natural-sort-order.html

Essayez ceci:

import re 

def sort_nicely(l): 
    """ Sort the given list 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) ] 
    l.sort(key=alphanum_key) 
+0

J'utiliserais 'text.lower()' à la fin de la ligne 'convert =' pour le rendre insensible à la casse. – kindall

+0

+1. Vous pouvez remplacer le lambda par une définition de fonction appropriée, pour plus de lisibilité. Incidemment, les numéros de version du paquet Debian sont comparés plus ou moins comme ça. http://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Version –

+1

+1 Bonne réponse. La seule chose que je n'aime pas, ce sont des espaces blancs supplémentaires. Je veux dire ici: '[convert (c) pour c dans re.split ('([0-9] +)', touche)]' et 'l.sort (clé = alphanum_key)' et 'sort_nicely (l)' –

0

Utilisez list.sort() et fournir votre propre fonction pour l'argument key. Votre fonction sera appelée pour chaque élément de la liste (et passé l'élément), et devrait renvoyer une version de cet élément qui sera triée.

Voir http://wiki.python.org/moin/HowTo/Sorting/#Key_Functions pour plus d'informations.

0

Si vous voulez ignorer complètement les cordes, alors vous devriez faire

import re 
numre = re.compile('[0-9]+') 
def extractNum(s): 
    return int(numre.search(s).group()) 

myList = ["a143.txt", "a9.txt", ] 
myList.sort(key=extractNum) 
+0

Pourquoi le downvote? – highBandWidth

0

list.sort() est dépréciée (voir Python.org How-To). sorted(list, key=keyfunc) c'est mieux.

import re 

def sortFunc(item): 
    return int(re.search(r'[a-zA-Z](\d+)', item).group(1)) 

myList = ["a143.txt", "a9.txt"] 

print sorted(myList, key=sortFunc) 
+0

list.sort() est obsolète? "Habituellement c'est moins pratique que trié()" est la seule chose dans cette direction que j'ai trouvée. Je dois dire, cependant, que je serais plus qu'heureux de voir disparaître le tri sur place, mais cela semble improbable. – tokland

+1

Ce n'est pas obsolète. http://docs.python.org/library/stdtypes.html#mutable-sequence-types –

+0

Il peut ne pas être techniquement déprécié mais il est considéré comme la "vieille" méthode et est étiqueté comme tel sur Python.org. – Prydie

0
>>> paths = ["a143.txt", "a9.txt"] 
>>> sorted(paths, key=lambda s: int(re.search("\d+", s).group())) 
['a9.txt', 'a143.txt'] 

Plus générique, si vous voulez que cela fonctionne aussi pour les fichiers comme: a100_32_12 (et le tri par des groupes numériques):

>>> paths = ["a143_2.txt", "a143_1.txt"] 
>>> sorted(paths, key=lambda s: map(int, re.findall("\d+", s))) 
['a143_1.txt', 'a143_1.txt']