Wie sortiere ich eine Liste von Zeichenfolgen numerisch?


127

Ich weiß, dass dies trivial klingt, aber ich wusste nicht, dass die sort()Funktion von Python seltsam war. Ich habe eine Liste von "Zahlen", die tatsächlich in Zeichenfolgenform vorliegen, also konvertiere ich sie zuerst in Ints und versuche dann eine Sortierung.

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

list1.sort()
print list1

Gibt mir:

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

Was ich will ist

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

Ich habe mich nach einigen Algorithmen umgesehen, die mit dem Sortieren von numerischen Sätzen verbunden sind, aber alle, die ich gefunden habe, beinhalten das Sortieren von alphanumerischen Sätzen.

Ich weiß, dass dies wahrscheinlich ein Kinderspiel ist, aber Google und mein Lehrbuch bieten nichts mehr oder weniger Nützliches als die .sort()Funktion.


9
Beachten Sie, dass Ihre for-Schleife nicht das tut, was ich vermute.
Deinst

1
Sie haben zu keinem Zeitpunkt ein Update durchgeführt list1. Warum hast du gedacht, listdass es aktualisiert wird?
S.Lott

Das ähnliche Problem tritt auf, wenn list1 = ['1', '1.10', '1.11', '1.1', '1.2'] als Eingabe bereitgestellt wird. Anstatt die Ausgabe als ['1', '1.1', '1.2', '1.10', '1.11'] zu erhalten, erhalte ich ['1', '1.1', '1.10', '1.11', '1.2' ]
Sathish

2
in Python 3 möchten Sie vielleicht verwendensorted(mylist)
Akin Hwan

Antworten:


191

Sie haben Ihre Zeichenfolgen nicht in Ints konvertiert. Oder besser gesagt, Sie haben es getan, aber dann haben Sie nichts mit den Ergebnissen gemacht. Was Sie wollen ist:

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

Wenn Sie aus irgendeinem Grund Zeichenfolgen anstelle von Ints beibehalten müssen (normalerweise eine schlechte Idee, aber möglicherweise müssen Sie führende Nullen oder ähnliches beibehalten), können Sie eine Schlüsselfunktion verwenden. sortNimmt einen benannten Parameter, keyeine Funktion, die für jedes Element aufgerufen wird, bevor es verglichen wird. Die Rückgabewerte der Tastenfunktion werden verglichen, anstatt die Listenelemente direkt zu vergleichen:

list1 = ["1","10","3","22","23","4","2","200"]
# call int(x) on each element before comparing it
list1.sort(key=int)

8
Wenn ich key = int in 2.7 versuche, bekomme ich None
KI4JGT

1
Dies funktioniert, wenn das Listenelement als "Ganzzahl" gespeichert ist. Wie soll bei Float-Werten umgegangen werden? ZB list1 = [1, 1.10, 1.11, 1.1, 1.2]
sathish

1
@ KI4JGT Die Sortiermethode ändert die Liste und gibt None zurück. list1 = list1.sort(key=int)Verwenden Sie stattdessen stattdessen just list1.sort(key=int)und list1 wird bereits sortiert.
Josiah Yoder

1
@ KI4JGT .sort () ist ein In-Place-Operator, es gibt None zurück, es sortiert die Liste, Sie können sorted () verwenden
sherpya

39

Sie können eine Funktion an den keyParameter an die .sortMethode übergeben . Damit sortiert das System nach Schlüssel (x) anstelle von x.

list1.sort(key=int)

Übrigens, um die Liste dauerhaft in Ganzzahlen umzuwandeln, verwenden Sie die mapFunktion

list1 = list(map(int, list1))   # you don't need to call list() in Python 2.x

oder Listenverständnis

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

21

Wenn Sie die sorted()Funktion verwenden möchten :sorted(list1, key=int)

Es wird eine neue sortierte Liste zurückgegeben.


1
Funktioniert auch mit Sets!
MT

12

Pythons Sorte ist nicht sonderbar. Es ist nur so, dass dieser Code:

for item in list1:
   item=int(item)

tut nicht das, was du denkst - itemwird nicht wieder in die Liste aufgenommen, sondern einfach weggeworfen.

Wie auch immer, die richtige Lösung ist, key=intwie andere Ihnen gezeigt haben.


12

Sie können auch verwenden:

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

Dies ist sehr ähnlich zu anderen Sachen, die Sie im Internet finden können, funktioniert aber auch für alphanumerische wie [abc0.1, abc0.2, ...].


8

Die Antwort von Seamus Campbell funktioniert unter python2.x nicht.
list1 = sorted(list1, key=lambda e: int(e))Die Verwendung der lambdaFunktion funktioniert gut.


8

Ich habe mich gestern dem gleichen Problem genähert und ein Modul namens [natsort] [1] gefunden, das Ihr Problem löst. Verwenden:

from natsort import natsorted # pip install natsort

# Example list of strings
a = ['1', '10', '2', '3', '11']

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

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

# Your array may contain strings
[In]  natsorted(['string11', 'string3', 'string1', 'string10', 'string100'])
[Out] ['string1', 'string3', 'string10', 'string11', 'string100']

Es funktioniert auch für Wörterbücher als Äquivalent von sorted. [1]: https://pypi.org/project/natsort/


3

Versuchen Sie Folgendes: Die Liste wird in absteigender Reihenfolge sortiert (in diesem Fall muss kein Schlüssel angegeben werden):

Prozess

listB = [24, 13, -15, -36, 8, 22, 48, 25, 46, -9]
listC = sorted(listB, reverse=True) # listB remains untouched
print listC

Ausgabe:

 [48, 46, 25, 24, 22, 13, 8, -9, -15, -36]

0

Die neueste Lösung ist richtig. Sie lesen Lösungen als Zeichenfolge. In diesem Fall lautet die Reihenfolge 1, dann 100, dann 104, gefolgt von 2, dann 21, dann 2001001010, 3 usw.

Sie müssen stattdessen Ihre Eingabe als int CAST:

sortierte Zeichenfolgen:

stringList = (1, 10, 2, 21, 3)

sortierte Ints:

intList = (1, 2, 3, 10, 21)

Zum Casting setzen Sie einfach die stringList in int (blahblah).

Nochmal:

stringList = (1, 10, 2, 21, 3)

newList = int (stringList)

print newList

=> returns (1, 2, 3, 10, 21) 

1
TypeError: int () Argument muss eine Zeichenfolge oder eine Zahl sein, nicht 'Tupel'
Cees Timmerman

Außerdem sollten die Zeichenfolgen in Ihrer Zeichenfolgenliste in Anführungszeichen gesetzt werden.
Teepeemm

2
Das ist eine verdammt gute Vorhersage: "Die neueste Lösung ist richtig";)
GreenAsJade

0

Wenn Sie Zeichenfolgen der Zahlen verwenden möchten, nehmen Sie besser eine andere Liste, wie in meinem Code gezeigt, es wird gut funktionieren.

list1=["1","10","3","22","23","4","2","200"]

k=[]    
for item in list1:    
    k.append(int(item))

k.sort()
print(k)
# [1, 2, 3, 4, 10, 22, 23, 200]

0

Einfache Möglichkeit, eine numerische Liste zu sortieren

numlists = ["5","50","7","51","87","97","53"]
results = list(map(int, numlists))
results.sort(reverse=False)
print(results)

-1

Das eigentliche Problem ist, dass die Sortierung die Dinge alphanumerisch sortiert. Wenn Sie also eine Liste ['1', '2', '10', '19'] haben und sort ausführen, erhalten Sie ['1', '10'. '19', '2']. dh 10 kommt vor 2, weil es das erste Zeichen betrachtet und danach sortiert. Es scheint, dass die meisten Methoden in Python die Dinge in dieser Reihenfolge zurückgeben. Wenn Sie beispielsweise ein Verzeichnis mit dem Namen abc haben, dessen Dateien mit 1.jpg, 2.jpg usw. gekennzeichnet sind, sagen Sie bis zu 15.jpg, und Sie file_list = os.listdir (abc) ausführen, wird die file_list nicht wie erwartet sortiert, sondern als file_list = ['1.jpg', '11 .jpg '---' 15.jpg ',' 2.jpg]. Wenn die Reihenfolge, in der Dateien verarbeitet werden, wichtig ist (vermutlich haben Sie sie deshalb numerisch benannt), entspricht die Reihenfolge nicht Ihrer Meinung nach. Sie können dies vermeiden, indem Sie "Nullen" auffüllen. Wenn Sie beispielsweise eine Liste alist = ['01', '03', '05', '10', '02', '04', '06] haben und darauf sortieren, erhalten Sie die gewünschte Reihenfolge. alist = ['01', '02' usw.], da das erste Zeichen 0 ist, das vor 1 steht. Die Anzahl der benötigten Nullen wird durch den größten Wert in der Liste bestimmt. Zum Beispiel, wenn das größte zwischen 100 und 100 liegt 1000 müssen Sie einzelne Ziffern als 001, 002 --- 010,011--100, 101 usw. auffüllen.


-5
scores = ['91','89','87','86','85']
scores.sort()
print (scores)

Dies funktionierte bei mir mit Python Version 3, in Version 2 jedoch nicht.


3
Versuchen Sie dort mit '11 und '100' zu sortieren, dann wird es interessant.
Penz
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.