sort() nur bestimmten inhalt

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
Zack
User
Beiträge: 47
Registriert: Dienstag 24. April 2007, 11:19

Ich würde gerne eine Liste anhand von einem kleinen Bereich jedes Elements sortieren. Naja, kurz gesagt: Ich hab jeweils ein String in dem am ende in Klammern eine id steht. Nach dieser würde ich gerne sortieren.

Code: Alles auswählen

def getid(t):
    return int(t[-5:-1])

chrono.sort(key = getid)
Leider klappt das so scheinbar nicht. Ich vermute weil es kein mehrdimensionales Array/Liste ist. Ich hab aber leider keine Umsetzung für nur einfache Arrays/Listen gefunden, entwickeln können.

Inhald sieht zb wie folgt aus:

Code: Alles auswählen

chrono = ['dell4wobe PROC01: WNS(10000)', 'dell4wobe PROC01: WNS(10056)', 'dell4wobe PROC01: WNS(10188)', 'Blacksheep PROC01: WNS(4832)', 'dell4wobe PROC01: WNS(2548)', 'default']
Ich hab beim stöbern auch diese Variante gefunden:

Code: Alles auswählen

sorted(chrono, key=lambda s: int(s[s.index('(') + 1:s.rindex(')')]))
Leider bekomme ich dabei immer ein "exceptions.ValueError: substring not found"

Hoffe ihr könnt mir helfen.
Gruß Zack
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Zack hat geschrieben:

Code: Alles auswählen

def getid(t):
    return int(t[-5:-1])

chrono.sort(key = getid)
Hallo Zack!

Die Werte sind unterschiedlich lang. Du musst vorher herausfinden, wo die öffnende Klammer steht.

Code: Alles auswählen

>>> chrono = ['dell4wobe PROC01: WNS(10000)', 'dell4wobe PROC01: WNS(10056)', 
...     'dell4wobe PROC01: WNS(10188)', 'Blacksheep PROC01: WNS(4832)', 
...     'dell4wobe PROC01: WNS(2548)']
>>> def get_key(value):
...     return int(value[value.rfind("(") + 1:-1])
...     
>>> get_key(chrono[0])
10000
>>> sorted(chrono, key = get_key)
['dell4wobe PROC01: WNS(2548)', 'Blacksheep PROC01: WNS(4832)', 
'dell4wobe PROC01: WNS(10000)', 'dell4wobe PROC01: WNS(10056)', 
'dell4wobe PROC01: WNS(10188)']
>>> 
mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Zack
User
Beiträge: 47
Registriert: Dienstag 24. April 2007, 11:19

Hab's geschafft. Beid der zweiten Variante mussten vorher die "default"-Werte ausgefiltert werden.

Code: Alles auswählen

for i in chrono:
    try: int(i[-5:-1])
    except: chrono.remove(i)
Schön sich selbst helfen zu können =)

edit: Ah danke gerold, dass habe ich ganz übersehen.
Zuletzt geändert von Zack am Dienstag 5. Februar 2008, 12:11, insgesamt 2-mal geändert.
BlackJack

Das erste kann nicht Funktionieren weil Du verschieden lange Zahlen hast:

Code: Alles auswählen

In [318]: 'dell4wobe PROC01: WNS(10188)'[-5:-1]
Out[318]: '0188'
Das zweite Funktioniert mit den Beispieldaten, die Du zeigst ganz prima:

Code: Alles auswählen

In [319]: sorted(chrono, key=lambda s: int(s[s.index('(') + 1:s.rindex(')')]))
Out[319]:
['dell4wobe PROC01: WNS(2548)',
 'Blacksheep PROC01: WNS(4832)',
 'dell4wobe PROC01: WNS(10000)',
 'dell4wobe PROC01: WNS(10056)',
 'dell4wobe PROC01: WNS(10188)']
Die Ausnahme ist eigentlich auch recht klar: Mindestens eine Zeichenkette auf der Liste auf der Du das *wirklich* anwendest hat keine Zahl in Klammern, weil eine der Klammern nicht gefunden werden kann.
BlackJack

Ups. War zu langsam. :-)

@Zack: Dein Filtern funktioniert nicht zuverlässig. Wenn man eine Liste verändert, über die man gerade iteriert, können Elemente "übersprungen" oder mehrfach besucht werden. Benutze am besten `filter()` oder eine "list comprehension" mit ``if``, um eine neue Liste ohne die Default-Werte zu erstellen.
Zack
User
Beiträge: 47
Registriert: Dienstag 24. April 2007, 11:19

Ah, wieder was gelernt $)
Danke euch, wie immer super hilfreich :)
Gruß Zack
Antworten