Hallo,
ich möchte eine Zahl vom Anfang eines Strings auslesen. Der String sieht zum Beispiel so aus aus "12Akajnajfaj34fjakfjka5kjkj". Jetzt möchte ich nur noch die 12 haben. Wie geht das am einfachsten?
Danke
Zahl vom Anfang eines Strings auslesen
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Mit einem regulären Ausdruck:
Wenn Du die Suche öfter durchführst, dann würde ich den Ausdruck noch kompilieren mit `re.compile`.
Code: Alles auswählen
In [5]: import re
In [6]: res = re.search(r"\d+", "12Akajnajfaj34fjakfjka5kjkj")
In [7]: res.group()
Out[7]: '12'
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
Ein regulärer Ausdruck mit dem 're'-Modul wäre wohl auch meine erste Wahl.
Andererseits vermeidet Python soweit wie möglich reguläre Ausdrücke und verwendet stattdessen besser lesbare Funktionen wie ".startswith()" oder ".replace()".
Ich könnte mir also auch sowas vorstellen:
Muß aber nicht. 're' ist auch ok (und wahrscheinlich auch schneller), wenn man damit umgehen kann (was z.B. für Anfänger wohl nicht so ganz leicht ist).
Andererseits vermeidet Python soweit wie möglich reguläre Ausdrücke und verwendet stattdessen besser lesbare Funktionen wie ".startswith()" oder ".replace()".
Ich könnte mir also auch sowas vorstellen:
Code: Alles auswählen
a = "12Akajnajfaj34fjakfjka5kjkj"
b = ""
while len(a) > 0 and a[0].isdigit():
b += a[0]
a = a[1:]
print b
Anstelle mit Indices und `while` geht es auch wie folgt ganz schön:
Ansonsten ginge auch folgendes. Allerdings bin ich mir nicht sicher, ob das Verhalten gewollt ist:
Grüße
Gerrit
Code: Alles auswählen
In [36]: a = "12Akajnajfaj34fjakfjka5kjkj"
In [37]: b = ''
In [38]: for c in a:
....: if c.isdigit():
....: b += c
....: else:
....: break
....:
In [39]: b
Out[39]: '12'
Code: Alles auswählen
In [33]: def break_():
....: raise StopIteration
....:
In [34]: a = "12Akajnajfaj34fjakfjka5kjkj"
In [35]: ''.join(c if c.isdigit() else break_() for c in a)
Out[35]: '12'
Gerrit
Stimmt, das gefällt mir auch viel besser.gkuhl hat geschrieben:Code: Alles auswählen
In [36]: a = "12Akajnajfaj34fjakfjka5kjkj" In [37]: b = '' In [38]: for c in a: ....: if c.isdigit(): ....: b += c ....: else: ....: break
Danke an alle!
Ich verwende erst einmal die Lösung von gkuhl, werde aber auch noch die re-Variante ausprobieren.
Ich verwende erst einmal die Lösung von gkuhl, werde aber auch noch die re-Variante ausprobieren.
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Was heißt "Python" vermeidet etwas? Der Interpreter? Die Sprache an sich? Belege?problembär hat geschrieben: Andererseits vermeidet Python soweit wie möglich reguläre Ausdrücke und verwendet stattdessen besser lesbare Funktionen wie ".startswith()" oder ".replace()".
Oha... eine schlechtere Lösung ist kaum vorstellbar! Das Laufzeitverhalten davon ist furchtbar, vom Speicherverbrauch mal abgesehen. Ist Dir klar, was da alles passiert im einzelnen?problembär hat geschrieben: Ich könnte mir also auch sowas vorstellen:Code: Alles auswählen
a = "12Akajnajfaj34fjakfjka5kjkj" b = "" while len(a) > 0 and a[0].isdigit(): b += a[0] a = a[1:] print b
Die Variante von gkuhl ist da schon besser; sinnvoller Weise vergisst man mal schnell die Stringkonkatenation mittels "+" und nutzt eine Liste und anschließend `join`:
Code: Alles auswählen
In [46]: res = []
In [47]: for c in data:
....: if c.isdigit():
....: res.append(c)
....: else:
....: break
....:
....:
In [48]: res
Out[48]: ['1', '2']
In [49]: "".join(res)
Out[49]: '12'
Code: Alles auswählen
In [44]: from itertools import takewhile
In [45]: "".join(takewhile(lambda c: c.isdigit(), data))
Out[45]: '12'
@Lasse: Mal ganz im Ernst: Die Lösung mit dem `re`-Modul ist am einfachsten - das sollte auch ein Anfänger sehen.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
@gkuhl: Eine Iteratorlösung ginge auch mit `operator.methodcaller()` (oder einer ``lambda``-Funktion) und `itertools.takewhile()`:
Edit: Mist, zu langsam.
Code: Alles auswählen
In [101]: ''.join(takewhile(methodcaller('isdigit'), a))
Out[101]: '12'
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Yihaaa! Zum ersten Mal BlackJack "geschlagen"BlackJack hat geschrieben: Edit: Mist, zu langsam.
...
Wobei ich `methodcaller` noch nicht kannte... ist das eigentlich `lambda` zu bevorzugen? (Wieso eigentlich `method` und nicht `function`?)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Ich sollte zu Bett gehen... danke!nomnom hat geschrieben:Vielleicht, weil es Methoden und keine Funktionen aufruft?Hyperion hat geschrieben:Wieso eigentlich `method` und nicht `function`?
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
Ist das besser alsBlackJack hat geschrieben:Code: Alles auswählen
In [101]: ''.join(takewhile(methodcaller('isdigit'), a))
Code: Alles auswählen
''.join(takewhile(str.isdigit, a))
@bords0: Deine Variante kommt nicht mit "unicode"-Objekten klar:
Code: Alles auswählen
In [14]: a = u'12'
In [15]: ''.join(takewhile(methodcaller('isdigit'), a))
Out[15]: u'12'
In [16]: ''.join(takewhile(str.isdigit, a))
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/home/lunar/<ipython-input-16-112f36c1e07f> in <module>()
----> 1 ''.join(takewhile(str.isdigit, a))
TypeError: descriptor 'isdigit' requires a 'str' object but received a 'unicode'