Seite 1 von 1

Erweitertes split()

Verfasst: Sonntag 8. August 2010, 11:10
von mzh
Hallo zusammen
Gibt es eine Art erweitertes split(), welches erlauben würde, ein Argument zu splitten, auch wenn der delimiter nicht bekannt ist. Also, erst würde split() versuchen auf whitespace zu splitten, wenn kein whitespace vorhanden ist, dann auf ':', sonst auf '-' und sonst noch auf '_'. Das wäre die Idee.
Oder muss man das selber programmieren?

Besten Dank für Hinweise.

Re: Erweitertes split()

Verfasst: Sonntag 8. August 2010, 11:19
von BlackJack
@mzh: Das muss man wohl selber implementieren. Vielleicht auch unter Hilfe von `csv.Sniffer`!?

Re: Erweitertes split()

Verfasst: Sonntag 8. August 2010, 12:01
von jbs

Code: Alles auswählen

def split(s, seps, maxsplit=-1):
    for sep in seps:
        parts = s.split(sep, maxsplit)
        if len(parts) > 1:
            return parts
    return parts


print split('ab c', [' ', '-', ':'])
print split('ab-c', [' ', '-', ':'])
print split('ab:c', [' ', '-', ':'])
print split('ab!c', [' ', '-', ':'])

Re: Erweitertes split()

Verfasst: Sonntag 8. August 2010, 12:14
von Barabbas
@jbs: Sowas habe ich auch erst überlegt - ich glaube aber, dass es effizienter ist, nicht "blind" zu splitten, sondern zu prüfen, ob der Delim im String vorkommt:

Code: Alles auswählen

def splitit(s, seps, maxsplit=-1):
    for sep in seps:
        if sep in s:
            return s.split(sep, maxsplit)
Falls man in die Verlegenheit kommt, ein paar Millionen Zeichenketten auf diese Weise trennen zu müssen, kann das sicher durchaus mal eine Sekunde ausmachen ;)

Re: Erweitertes split()

Verfasst: Sonntag 8. August 2010, 12:15
von mzh
@jbs: Wieso setzt du 'maxsplit = -1'?

Code: Alles auswählen

>>> print 'sdljsf'.split.__doc__
S.split([sep [,maxsplit]]) -> list of strings

Return a list of the words in the string S, using sep as the
delimiter string.  If maxsplit is given, at most maxsplit
splits are done. If sep is not specified or is None, any
whitespace string is a separator and empty strings are removed
from the result.

Re: Erweitertes split()

Verfasst: Sonntag 8. August 2010, 12:19
von Barabbas
Weil das der Standardwert ist und besagt, dass die Zeichenkette an allen Vorkommen des Delimiters aufgetrennt wird. Ist maxsplit >= 0, wird die Zeichenkette nur an den ersten n-Vorkommen des Delimiters aufgetrennt.

Code: Alles auswählen

>>> "1,2,3".split(",",-1)
['1', '2', '3']
>>> "1,2,3".split(",",0)
['1,2,3']
>>> "1,2,3".split(",",1)
['1', '2,3']
Gruß,

brb

Re: Erweitertes split()

Verfasst: Sonntag 8. August 2010, 12:24
von mzh
aha, ja war nur verwirrt, weil von Standardwert nichts in der __doc__ stand. Ist also einfach eine Stilfrage, ob der explizit mitgegeben wird.

Re: Erweitertes split()

Verfasst: Sonntag 8. August 2010, 12:30
von jbs

Code: Alles auswählen

>>> ''.split(maxsplit=1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: split() takes no keyword arguments
Was soll das eigentlich?!

Ich möchte ja ein ähnliches Interface wie die originalmethode haben und daher gebe ich den Wert immer mit an.

Re: Erweitertes split()

Verfasst: Sonntag 8. August 2010, 12:47
von Leonidas
jbs hat geschrieben:

Code: Alles auswählen

>>> ''.split(maxsplit=1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: split() takes no keyword arguments
Was soll das eigentlich?!
Nicht alle in C implementierten Methoden nehmen in CPython Keywordargumente, liegt glaub ich daran dass die Argumente auf C-Ebene keine "Python-Namen" haben.

Re: Erweitertes split()

Verfasst: Sonntag 8. August 2010, 20:06
von derdon
Mit PyPy wär das nicht passiert :P