Gemeinsamen Anfang einer Liste finden...

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
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Für http://www.python-forum.de/post-72855.html#72855 benötige ich eine Funktion, die den gemeinsamen Anfang einer Liste feststellt.

Meine Aktuelle Variante, macht das rekursiv, es sieht so aus:

Code: Alles auswählen

def get_basename(filelist, basename=""):
    """
    Liefert die gemeinsame Basis aller Dateinamen zurück

    >>> get_basename(["abc1.txt", "abc2.txt", "abc3.txt"])
    'abc'
    >>> get_basename(["1.txt", "2.txt", "3.txt"])
    ''
    """
    first_fn = filelist[0]
    pos = len(basename)

    # nächsten Buchstaben einfügen
    new_basename = basename + first_fn[pos]

    for fn in filelist:
        if not fn.startswith(new_basename):
            # Eine Datei fängt nicht so an -> Basis gefunden
            return basename

    return get_basename(filelist, new_basename)
Wie geht's besser/schneller? (Obwohl es erstmal schnell genug für mich ist)

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Zap
User
Beiträge: 533
Registriert: Freitag 13. Oktober 2006, 10:56

Ich hatte irgendwie das Gefühl so eine Funktion schonmal als build-in
gesehen zu haben. Und so ist es auch :o

Code: Alles auswählen

>>> l = [ i for i in os.listdir(".") if i.endswith(".txt") ]
>>> l
['test.txt', 'test1.txt', 'test2.txt', 'test3.txt', 'test4.txt', 'test_neu.txt']
>>> os.path.commonprefix(l)
'test'
>>>
Oder habe ich was übersehen ?
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Damit hab ich nicht gerechnet... Ist ja super, dann nutzte ich das ;)

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Joghurt
User
Beiträge: 877
Registriert: Dienstag 15. Februar 2005, 15:07

jens hat geschrieben:Wie geht's besser/schneller?
Ich hätte es übrigens so gelöst(und anscheinend macht es commonprefix im Prinzip genauso)

Code: Alles auswählen

def common_prefix(names):
    sorted_names = sorted(names)
    first = sorted_names[0]
    last = sorted_names[-1]
    i = 0
    try:
        while first[i] == last[i]:
            i += 1
    except IndexError:
        pass
    return first[:i]
Andere Vorschläge?
Zap
User
Beiträge: 533
Registriert: Freitag 13. Oktober 2006, 10:56

ähnlich...
Ich geh davon aus das min/max schneller ist als ein sort auf strings.
Auch wenns 2 mal aufgerufen wird.

Code: Alles auswählen

def commonprefix(m):
    "Given a list of pathnames, returns the longest common leading component"
    if not m: return ''
    s1 = min(m)
    s2 = max(m)
    n = min(len(s1), len(s2))
    for i in xrange(n):
        if s1[i] != s2[i]:
            return s1[:i]
    return s1[:n]
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Zap hat geschrieben:ähnlich...
Ich geh davon aus das min/max schneller ist als ein sort auf strings.
Warum?
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
BlackJack

Zumindest in O-Notation ist es O(n) gegen O(n·log(n)). Müsste man also messen ob's grundsätzlich einen Unterschied macht bzw. ab welchem n die `min()`/`max()`-Variante gegenüber dem Sortieren im Vorteil ist.
Antworten