Liste mit sorted() absteigend sortieren

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
tz_wuerzburg
User
Beiträge: 71
Registriert: Dienstag 7. März 2017, 17:51

Hallo Leute,
ich möchte eine Liste absteigend sortieren. Das ganze funktioniert leider nicht wie gewünscht.
Mein Ziel:
888
100
99
98
97
usw.

Das aktuelle Ergebnis:
99
98
97
888
100
usw.

Code: Alles auswählen

import csv
from operator import itemgetter

with open("bundle_5digits_x_counter_ID.csv","r") as input:
    entry_address = csv.reader(input, delimiter=";")
    sort_ID = sorted(entry_address, key=itemgetter(12), reverse=True)
    for address_line in sort_ID:
            
        print (address_line)
Das sorted Howto habe ich mir angesehen, aber keine Lösung gefunden.
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Du hast sorted() noch nicht verstanden. So wie du es machst, sortiert er für jeden Datensatz die einzelnen Zeileneinträge. Du willst aber wahrscheinlich alle Datensätze nach einem bestimmten Kriterium sortieren. Das geht in etwa so:

Code: Alles auswählen

import csv

CSV_FILENAME = 'bundle_5digits_x_counter_ID.csv'
SORT_INDEX = 12

def main():
    with open(CSV_FILENAME) as csv_file:
        datasets = csv.reader(csv_file, delimiter=';')
    result = sorted(
        datasets, key=lambda x: x[SORT_INDEX], reverse=True
    )
    print('\n'.join(result))

if __name__ == '__main__':
    main()
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

snafu hat geschrieben:Du hast sorted() noch nicht verstanden.
Ich verstehe nicht, wie tz_wuerzburg »sorted« nicht verstanden haben soll.

@tz_wuerzburg: Dein Problem ist, dass Du Strings sortierst und nicht Zahlen, Du mußt die Spalte erst in Zahlen umwandeln, bevor Du sie sortierst.

Code: Alles auswählen

import csv
 
CSV_FILENAME = 'bundle_5digits_x_counter_ID.csv'
SORT_INDEX = 12
 
def main():
    with open(CSV_FILENAME) as csv_file:
        datasets = csv.reader(csv_file, delimiter=';')
        datasets = sorted(
            datasets, key=lambda x: int(x[SORT_INDEX]), reverse=True
        )
    for entry in datasets:
        print(entry)
 
if __name__ == '__main__':
    main()
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Es sah für mich so aus, als wenn der OP über die Datensätze von csv.reader() iteriert und sorted() auf jeden einzelnen Datensatz anwendet. Entweder es wurde editiert oder ich habe mich übelst verlesen.
Benutzeravatar
DeaD_EyE
User
Beiträge: 1016
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Ist schon ganz cool, dass du itemgetter verwendest und mit sorted einfach über das csv.reader-Objekt iterierst.

Du hast vergessen, dass hier strings verglichen werden. Du solltest die zu verlgeichenden werte erst in integer umwandeln und dann vergleichen.

Code: Alles auswählen

dev converter(row):
    try:
        return int(row[12])
    except ValueError:
        return -1
    except IndexError:
        return -2
Anstatt itemgetter(12) nimmst du jetzt einfach den converter.
Als erstes kämen die Datensätze mit weniger als 13 Spalten. Danach kommen die Datensätze, bei denen die Spalte 12 sich nicht in einen Integer umwandeln lässt und dann von 0 ansteigend.

Die Werte -1 und -2 koennen beliebige Werte sein, muessen aber vom datentyp float oder integer sein. Meistens ist es aber besser, wenn man zuerst daten filtert, die bestimmten Kriterien nicht entsprechen wie z.B Spalte 12 muss einen integer enthalten und anderes wird nicht durchgelassen.

Geschrieben mit einem chinesischen Handy
谢谢
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ja genau, und dann muss man die verschiedenen Minuswerte wieder zurück übersetzen. Halte ich für keine gute Idee. Das ist ein Aushebeln des fortschrittlichen Exception-Mechanismus durch traditionelle primitive Techniken. Fehlt am Ende nur noch das switch-Statement...
tz_wuerzburg
User
Beiträge: 71
Registriert: Dienstag 7. März 2017, 17:51

So funktioniert es jetzt.

Code: Alles auswählen

import csv

with open("bundle_5digits_x_counter_ID.csv","r") as input:
    entry_address = csv.reader(input, delimiter=";")
    sort_ID = sorted(entry_address, key=lambda x: int(x[12]), reverse=True)
    for address_line in sort_ID:
        
        print (address_line)
Ich habe nur noch nicht verstanden was passiert. lambda wandelt den Key für die Berechnung in ein int um?
Die Variable x wird zu int(x[Wert]) welche mit lambda dann übergeben wird.
In die lambda Geschichte werde ich mich morgen einlesen.

Vielen Dank für Eure Hilfe!
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

lambda ist eine anonyme Funktion, x ist der Parameter der Funktion. Hinter dem Doppelpunkt steht die Rückgabe der Funktion (muss immer ein Einzeiler sein). Das key-Argument von sorted() erwartet eine Funktion, die einen Parameter annimmt. Dies wird durch das eingesetzte lambda in dieser Form erfüllt.
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

snafu hat geschrieben:Es sah für mich so aus, als wenn der OP über die Datensätze von csv.reader() iteriert und sorted() auf jeden einzelnen Datensatz anwendet. Entweder es wurde editiert oder ich habe mich übelst verlesen.
Es lag wahrscheinlich einfach an der irreführenden Namensvergabe des OPs. Und dass ich es nur überflogen habe in der Annahme, hinter entry_address würde wirklich nur eine einzelne Adresse stecken...
Antworten