Seite 1 von 1

sort() nur bestimmten inhalt

Verfasst: Dienstag 5. Februar 2008, 11:51
von Zack
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

Re: sort() nur bestimmten inhalt

Verfasst: Dienstag 5. Februar 2008, 12:04
von gerold
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
:-)

Verfasst: Dienstag 5. Februar 2008, 12:09
von Zack
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.

Verfasst: Dienstag 5. Februar 2008, 12:09
von 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.

Verfasst: Dienstag 5. Februar 2008, 12:14
von 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.

Verfasst: Dienstag 5. Februar 2008, 15:22
von Zack
Ah, wieder was gelernt $)
Danke euch, wie immer super hilfreich :)
Gruß Zack