String ab dem ersten Vorkommen eines Zeichens ausgeben

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
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Nabend!

Ich spiele gerade ein bißchen mit ctypes und stöbere dafür auch in der clib rum. Ich bin nun auf die Funktionen strchr()/strrchr() gestoßen, mit denen es ja möglich ist, einen Zeiger zum ersten bzw letzten Vorkommen eines chars zu setzen und dann den String erst ab dieser Stelle ausgegeben zu lassen. Etwa so:

Code: Alles auswählen

In [1]: import charslice

In [2]: s = 'foobarbaz'

In [3]: charslice.fromfirst(s, 'b')
Out[3]: 'barbaz'

In [4]: charslice.fromlast(s, 'b')
Out[4]: 'baz'
Meine Frage: Gibt es dazu eigentlich ein Gegenstück in Python? Bisher implementiere ich das über den direkten Aufruf der C-Funktion:

Code: Alles auswählen

from ctypes import CDLL, c_char_p, c_char

libc = CDLL('libc.so.6')
funcs = {}
for func in ['strchr', 'strrchr']:
    cfunc = getattr(libc, func)
    cfunc.argtypes = [c_char_p, c_char]
    cfunc.restype = c_char_p
    funcs[func] = cfunc

def fromfirst(s, char): return funcs['strchr'](s, char)

def fromlast(s, char): return funcs['strrchr'](s, char)
EDIT: Okay, keine direkte Funktion, aber hab jetzt find() bzw. rfind() entdeckt. ^^

Code: Alles auswählen

def fromfirst(s, sub):
    return s[s.find(sub):]
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

Du kannst auch index und rindex benutzen, deren einziger Unterschied zu find / rfind ist, daß find / rfind bei Nichtvorkommen -1 zurückgeben, während index / rindex einen ValueError werfen, was für deine Verwendung praktischer sein dürfte.
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Joa, gut. Etwas idiomatischer wäre wohl das Exceptionhandling:

Code: Alles auswählen

def fromfirst(s, sub):
    try:
        return s[s.index(sub):]
    except ValueError:
        return
Ansonsten würd ich's so machen:

Code: Alles auswählen

def fromfirst(s, sub):
    occur = s.find(sub)
    if occur != -1:
        return s[occur:]
Immitiert das anfangs genannte Verhalten natürlich nicht ganz exakt, da "sub" im Gegensatz zu "char" ja mehr als ein Zeichen sein darf, aber das halte ich auch eher für einen Vorteil.

BTW: So ein Singleton für -1 wäre ja vielleicht auch mal ganz nützlich. Auch wenn ich nicht wüsste, wie man das nennen soll. Also ich meine, dass Python sich quasi vorher die Funktion anschaut, ob sie explizit -1 bzw das Singleton in bestimmten Fällen zurückgeben kann und dies dann als unwahre Bedingung ansieht, wodurch ein Index von 0 oder 1 in diesem Fall nicht mehr als Wahrheitswert interpretiert würde.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

snafu hat geschrieben:BTW: So ein Singleton für -1 wäre ja vielleicht auch mal ganz nützlich. Auch wenn ich nicht wüsste, wie man das nennen soll. Also ich meine, dass Python sich quasi vorher die Funktion anschaut, ob sie explizit -1 bzw das Singleton in bestimmten Fällen zurückgeben kann und dies dann als unwahre Bedingung ansieht, wodurch ein Index von 0 oder 1 in diesem Fall nicht mehr als Wahrheitswert interpretiert würde.
Hmm, klingt für mich nach einer menge Magie die schwer überschaubar ist und dessen Nutzen bis auf dass es komplexer wird zumindest mir nicht einleuchtet. Mach doch mal ein Beispiel, wie deine Idee ein solches Problem klarer lösen kann als ein Test auf -1 oder, was ich mehr pythonic finde, Exceptions fängt.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Äußerst hilfreich ist auch oft das recht neue str.partition().
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

@Leonidas: Es wäre halt eher kosmetischer Natur. Ähnlich wie True für 1 und False für 0, die ja auch keine fundamentalen Änderungen mit sich bringen, sondern einfach nur lesbarer sind. -1 wäre dann False und alles andere True (außer leerer String und None natürlich). Ändern würde sich in dem Beispiel das Testen in if occur:. War aber auch nur so eine Idee...
BlackJack

@snafu: Ich finde man sollte mit -1 als "speziellen" Rückgabewert überhaupt nicht arbeiten. Das ist finsterstes Programmiersprachenmittelalter.

Genauso wie mir an Deiner Funktion missfällt, dass dort `None` als "Fehlerwert" herhalten muss.
Antworten