Sortierung Directory nach Vorgabe

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
mpe
User
Beiträge: 4
Registriert: Sonntag 23. Februar 2014, 21:19

Hallo zusammen,

Ich hab da ein Problem wo ich nicht weiterkomme. Es geht darum ein Directory nach keys zu sortieren und zwar so wie ich es vorgebe.
Als keys existieren Zahlen und auch Wörter. Ich möchte gerne zuerst die Zahlen absteigend und danach die Wörter Alphabetisch absteigend sortiert haben.
Wie zum Beispiel:

Code: Alles auswählen

{'1': 'Blabla', '2': 'Blabla', '15': 'Blabla', 'A1': 'Blabla', 'Trk1': 'Blabla'}
Mein Directory:

Code: Alles auswählen

{'18': (['20'], [], ['Down', '1000FDx']), '19': (['22'], [], ['Down', '1000FDx']), '12': ([], ['13', '15', '16', '17', '21', '22', '91', '92', '94', '99', '120', '253'], ['Up', '1000FDx']), 'Trk1': (['10'], [], ['Up', '1000FDx']), 'Trk2': (['20'], [], ['Up', '1000FDx']), '11': (['110'], [], ['Up', '1000FDx']), '17': (['20'], [], ['Down', '1000FDx']), '23': (['20'], [], ['Down', '1000FDx']), '22': (['22'], [], ['Down', '1000FDx']), '21': (['22'], [], ['Up', '1000FDx']), '20': (['22'], [], ['Down', '1000FDx']), '24': (['20'], [], ['Down', '1000FDx']), 'A2': (['1'], [], ['none', 'none']), 'A1': (['1'], [], ['none', 'none']), 'B2': ([], ['10', '13', '15', '16', '17', '20', '21', '22', '30', '40', '50', '60', '70', '80', '90', '91', '92', '94', '99', '100', '110', '120', '253'], ['Down', 'none']), 'B1': ([], ['10', '13', '15', '16', '17', '20', '21', '22', '30', '40', '50', '60', '70', '80', '90', '91', '92', '94', '99', '100', '110', '120', '253'], ['Up', '10GigFD']), '1': (['10'], [], ['Down', '1000FDx']), '2': (['20'], [], ['Down', '1000FDx']), '3': (['30'], [], ['Up', '1000FDx']), '4': (['40'], [], ['Up', '1000FDx']), '5': (['50'], [], ['Up', '1000FDx']), '6': (['60'], [], ['Up', '1000FDx']), '7': (['70'], [], ['Up', '1000FDx']), '8': (['80'], [], ['Up', '1000FDx']), '9': (['90'], [], ['Up', '1000FDx']), '10': (['100'], [], ['Up', '1000FDx'])}
Besten Dank für die Hilfe

Marc Peter
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

mpe hat geschrieben:Als keys existieren Zahlen und auch Wörter. Ich möchte gerne zuerst die Zahlen absteigend und danach die Wörter Alphabetisch absteigend sortiert haben.
Wie zum Beispiel:

Code: Alles auswählen

{'1': 'Blabla', '2': 'Blabla', '15': 'Blabla', 'A1': 'Blabla', 'Trk1': 'Blabla'}
Als Keys hast du aktuell ausschließlich Strings. Wenn ich dich richtig verstanden habe möchtest du die Strings, die ausschließlich aus Ziffern bestehen als Zahlen behandeln und dann absteigend sortieren. Dein Beispiel zeigt allerdings eine aufsteigende Sortierung. Dazu kommt noch, dass das Resultat kein Dictionary sein kann, da Dictionaries keine Sortierung beinhalten. Eine Liste aus Tupeln wäre allerdings möglich und die könnte man dann auch noch in ein OrderedDictionary übernehmen.

Was genau möchtest du denn jetzt als Ergebnis?

Gesetzt den Fall, deine Beschreibung stimmt, dann kannst du sorted verwenden und eine eigene Sortierfunktion mitgeben. Bei der Rückgabe der Sortierfunktion bietet sich ein Tupel an das als ersten Wert eine 0 enthält wenn es eine Zahl ist und eine 1 wenn es sich um einen String handelt. Damit hat man dann schon mal die Zahlen zuerst. Wenn jetzt eine Zahl vorliegt, dann konvertiert man sie tatsächlich in einen Integer-Wert und dreht dann noch das Vorzeichen um, damit man eine absteigende Reihenfolge erhält.

Die Funktion sorter erhält ein komplettes Item (also Key und Value) aus dem Dictionary. Für die Sortierung wird nur der Key benötigt.

Code: Alles auswählen

def sorter(item):
    key = item[0]
    if key.isdigit():
        return 0, -int(key)
    else:
        return 1, key.lower()

print(list(sorted(data.items(), key=sorter)))
Wenn du die Daten in einem OrderedDict haben möchtest geht das ganz einfach.

Code: Alles auswählen

from collections import OrderedDict
sorted_data = OrderedDict(sorted(data.items(), key=sorter))
Edit: OK, wahrscheinlich sind in deiner Beschreibung "absteigend" und "aufsteigend" falsch verwendet. Ich habe jetzt einfach mal demonstriert wie man nur die Zahlen absteigend sortiert. Solltest du tatsächlich grundsätzlich "aufsteigend" gemeint haben, dann brauchst du die ermittelte Zahl natürlich nicht negieren.
mpe
User
Beiträge: 4
Registriert: Sonntag 23. Februar 2014, 21:19

@/me
Danke für deine Hilfe,

Ja absteigend und aufsteigend hab ich verwechselt ;-)

Ich hab jetzt auch eine Lösung erarbeitet:
- Ich generiere eine Liste mit allen Keys des Dictionarys

Code: Alles auswählen

UnsortedList=Directory.keys()
- Daraus Generiere ich eine Liste mit Integer Keys und eine mit String Keys
- Sortiere beide Listen

Code: Alles auswählen

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 41, 42, 43, 44, 45, 46]

Code: Alles auswählen

['A1', 'A2', 'B1', 'B2', 'Trk1', 'Trk2']
- Mach aus der Integer Liste wieder Strings und setze sie mit der String Liste zusammen

Code: Alles auswählen

['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32', '33', '34', '35', '36', '37', '38', '41', '42', '43', '44', '45', '46', 'A1', 'A2', 'B1', 'B2', 'Trk1', 'Trk2']
- Wenn ich jetzt Durch mein Directory iteriere mach ich das über die Sortierte Liste und übergib so den Key dem Directory
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Deine Variante funktioniert durchaus und ist vermutlich auch für den ambitionierten Einsteiger problemlos zu verstehen. Ich mag das, wenn Leute sich selber etwas erarbeiten und nicht nur vorgekaute Lösungen verwenden.

Jetzt mal als Beispiel wie die Kurzfassung dieser Listengenerierung in Python aussehen könnte wenn data dein Dictionary ist.:

Code: Alles auswählen

print(sorted(data, key=lambda x: '{0:6}'.format(int(x)) if x.isdigit() else x))
Als Einsteiger stolpert man dort meistens über 2-3 Dinge:
  1. Der ternäre if-else Ausdruck
  2. Die Lambda-Funktion
  3. evtl. die format-Methode des Strings
Wenn du Zeit und Lust hast, dann versuch mal den Code zu verstehen. Du wirst dabei eine Menge über Python lernen. Wenn du keine Lust hast dann lass es, irgendwann kommt das (und bei Fragen sind wir ja auch noch da).
Antworten