Seite 1 von 1

dircache - anordnung von numerischen filenamen

Verfasst: Mittwoch 14. April 2010, 16:29
von thomas15
hallo alle,

ich haette eine triviale frage:

wie kann ich mir den inhalt eines verzeichnisses mit dircache numerisch richtig ausgeben lassen?

ich habe ein verzeichniss mit files die numerisch durchgezehlt sind:

1.em , 2.em , 10.em
usw.

beispiel mit ls:
so ist es

Code: Alles auswählen

$ ls
1.em 10.em 2.em
 
so sollte es sein

Code: Alles auswählen

$ ls -v
1.em 2.em 10.em
 
den gleichen effekt will ich mit dircache in python auch erreichen.
weiss jemand wie?

danke im vorraus!

Verfasst: Mittwoch 14. April 2010, 16:46
von Dav1d
AFAIR liefer dircache eine Liste zurück =>

Code: Alles auswählen

sorted(my_list)

Verfasst: Mittwoch 14. April 2010, 16:55
von thomas15
bitte ein bissl mehr info:

Code: Alles auswählen

sorted(dircache.listdir('.'))
oder wie?

Verfasst: Mittwoch 14. April 2010, 16:58
von BlackJack
@Dav1d: Und `listdir()` sortiert die Liste vorher auch, das ist also keine Lösung weil hier keine alphabetische Sortierung erwünscht ist, sondern eine nach den Zahlen in den Namen.

@thomas15: Du wirst Dir überlegen müssen wie man die Zahl aus dem Namen extrahiert und der `sort()`-Methode eine entsprechende `key`-Funktion mitgeben müssen. `sorted()` würde ich nicht nehmen denn Du hast ja schon eine Liste, die muss nicht noch einmal kopiert werden.

Verfasst: Mittwoch 14. April 2010, 17:00
von Dav1d
sorted, war nur als Hinweis gedacht, zum Nachschlagen http://wiki.python.org/moin/HowTo/Sorting

Verfasst: Mittwoch 14. April 2010, 17:02
von thomas15
danke euch beiden, ich wollte mich um das string parsen druecken.

meine benutzer speichern nach beliebigen mustern:

einmal
particle_1.em particle_10.em ...

andermal

particle1.em particle10.em ...

und nochmal

p1_1.em p1_10.em p2_1.em p2_10.em

dachte wenn es schon in ls eingebaut ist, warum sollte es nicht auch in python gehen.
wenn jemand eine bessere idee hat wie man die ls -v funtionalitaet integrieren koennte dann bitte melden! (letztes beispiel kann nicht mal ls 100% handeln)

danke!

Verfasst: Mittwoch 14. April 2010, 18:12
von BlackJack
@thomas15: So schwer ist das doch nicht. Du musst halt nur die einzelnen Komponenten trennen, also Zahlen von Nicht-Zahlen und die Zahlen auch in solche umwandeln.

Code: Alles auswählen

def key_func(string):
    result = list()
    for match in re.finditer(r'([\d]+)|([^\d]+)', string):
        number, no_number = match.groups()
        result.append(int(number) if number else no_number)
    return result
Und angewendet:

Code: Alles auswählen

In [39]: xs
Out[39]: ['p1_10.em', 'p2_10.em', 'p2_1.em', 'p1_1.em']

In [40]: sorted(xs, key=key_func)
Out[40]: ['p1_1.em', 'p1_10.em', 'p2_1.em', 'p2_10.em']

Verfasst: Donnerstag 15. April 2010, 09:31
von thomas15
@BlackJack
probiers mal aus. aber ich kann nicht alle kombinationen von dateinamen parsen.
Danke!!!!

Verfasst: Donnerstag 15. April 2010, 16:05
von derdon
BlackJack: Warum verwendest du nicht \D?

Verfasst: Donnerstag 15. April 2010, 16:44
von BlackJack
Kein besonderer Grund.

Verfasst: Donnerstag 15. April 2010, 16:51
von derdon
OK, "hätt ja könne sin" wie der Hesse sagt :lol:

Verfasst: Donnerstag 15. April 2010, 18:07
von HerrHagen

Code: Alles auswählen

>>> files = ['p1_10.em', 'p2_10.em', 'p2_1.em', 'p1_1.em']
>>> def extract_num(text):
	return int(''.join(char for char in text if char.isdigit()))

>>> files.sort(key=extract_num)
>>> files
['p1_1.em', 'p2_1.em', 'p1_10.em', 'p2_10.em']
MFG
HerrHagen

Verfasst: Donnerstag 15. April 2010, 18:19
von EyDu
Da mag wohl jemand die filter-Funktion nicht.

Verfasst: Donnerstag 15. April 2010, 18:50
von BlackJack
@HerrHagen: Ich würde mal sagen das war nix. Sieht für mich falsch sortiert aus. Ersetz das 'p' mal durch 'versuch' wenn's Messdatensätze sind oder 'szene' wenn es Videoframes sind. Dann wird's vielleicht deutlicher.

Verfasst: Freitag 16. April 2010, 01:48
von Leonidas
Mein Ansatz:

Code: Alles auswählen

import re

def int_or_bust(value):
     try:
         return int(value)
     except ValueError:
         return value

def key_func(entry):
    return [int_or_bust(e) for e in re.findall(r'\d+|\D+', entry)]

xs = ['p1_10.em', 'p2_10.em', 'p2_1.em', 'p1_1.em']

print sorted(xs, key=key_func)

Verfasst: Freitag 16. April 2010, 07:03
von nemomuk

Code: Alles auswählen

xs = ['p1_10.em', 'p2_10.em', 'p2_1.em', 'p1_1.em', 'p1_32.em']
def get_numbers(string):
    return [int(c) for c in string if c.isdigit()]
    
print sorted(xs, key=get_numbers)
Das hier wäre doch irgendwie schöner...

Verfasst: Freitag 16. April 2010, 08:10
von BlackJack
@ahojnnes: Wieso ist falsch schöner? Alle "Nichtziffern" werden nicht berücksichtigt und 'p11_0.em' hat den gleichen Schlüssel wie 'p1_10.em' wo letzteres einen kleineren haben sollte.

Verfasst: Freitag 16. April 2010, 11:27
von nemomuk
hehe, sehe es gerade ja...;-) war wohl etwas unausgeschlafen heute früh - nehme alles zurück und behaupte das Gegenteil.