187 votes

Comment trier une liste de chaînes de caractères numériquement

Je sais que cela semble trivial, mais je n'ai pas réalisé que la fonction sort() de Python était étrange. J'ai une liste de "nombres" qui sont en fait sous forme de chaîne, donc je les convertis d'abord en entiers, puis je tente un tri.

list1=["1","10","3","22","23","4","2","200"]
for item in list1:
    item=int(item)

list1.sort()
print list1

Me donne :

['1', '10', '2', '200', '22', '23', '3', '4']

Je veux

['1','2','3','4','10','22','23','200']

J'ai cherché des algorithmes associés au tri des ensembles numériques, mais ceux que j'ai trouvés impliquaient tous le tri des ensembles alphanumériques.

Je sais que c'est probablement un problème facile, mais Google et mon manuel ne proposent rien de plus ou moins utile que la fonction .sort().

221voto

Seamus Campbell Points 11752

Vous n'avez en fait pas converti vos chaînes en entiers. En fait, vous l'avez fait, mais vous n'avez rien fait avec les résultats. Ce que vous voulez, c'est:

list1 = ["1","10","3","22","23","4","2","200"]
list1 = [int(x) for x in list1]
list1.sort()

Si pour une raison quelconque vous devez conserver des chaînes au lieu d'entiers (généralement une mauvaise idée, mais peut-être avez-vous besoin de préserver les zéros de tête ou quelque chose du genre), vous pouvez utiliser une fonction clé. sort prend un paramètre nommé, key, qui est une fonction appelée sur chaque élément avant d'être comparée. Les valeurs de retour de la fonction clé sont comparées au lieu de comparer directement les éléments de la liste:

list1 = ["1","10","3","22","23","4","2","200"]
# appelle int(x) sur chaque élément avant de le comparer
list1.sort(key=int)
# ou si vous voulez le faire tout en une seule ligne
list1 = sorted([int(x) for x in list1])

73voto

rfaenger Points 62

J'ai abordé le même problème hier et j'ai trouvé un module appelé natsort, qui résout votre problème. Utilisez :

from natsort import natsorted # pip install natsort

# Exemple de liste de chaînes de caractères
a = ['1', '10', '2', '3', '11']

[In]  sorted(a)
[Out] ['1', '10', '11', '2', '3']

[In]  natsorted(a)
[Out] ['1', '2', '3', '10', '11']

# Votre tableau peut contenir des chaînes de caractères
[In]  natsorted(['string11', 'string3', 'string1', 'string10', 'string100'])
[Out] ['string1', 'string3', 'string10', 'string11', 'string100']

Cela fonctionne également pour les dictionnaires comme l'équivalent de sorted.

44voto

KennyTM Points 232647

Vous pourriez passer une fonction au paramètre key à la méthode .sort. Avec cela, le système triera par int(x) au lieu de x.

list1.sort(key=int)

En passant, pour convertir la liste en entiers de façon permanente, utilisez la fonction map

list1 = list(map(int, list1))   # vous n'avez pas besoin d'appeler list() en Python 2.x

ou avec une compréhension de liste

list1 = [int(x) for x in list1]

32voto

syam Points 480

Si vous souhaitez utiliser sorted() fonction : sorted(list1, key=int)

Il retourne une nouvelle liste triée.

19voto

Julian Points 315

Vous pouvez également utiliser :

import re

def sort_human(l):
    convert = lambda text: float(text) if text.isdigit() else text
    alphanum = lambda key: [convert(c) for c in re.split('([-+]?[0-9]*\.?[0-9]*)', key)]
    l.sort(key=alphanum)
    return l

Ce qui est très similaire à d'autres choses que vous pouvez trouver sur internet mais fonctionne également pour des alphanumériques comme [abc0.1, abc0.2, ...].

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X