Seite 1 von 2
String modifizieren
Verfasst: Freitag 29. Januar 2010, 03:21
von mit
Hallo,
Ich habe folgende Strings:
las|6-1-1643-1438-1
7-1-1544-1338-1
Die "1" an der letzten stelle würde ich ganz gerne mit einer "2" ersetzen. Wobei die länge der Strings variieren könnte, d.h. die Anzahl von "-".
Könnte man dies mit Regulär Expression lösen oder gibt es dafür eine andere Methode?
Viele Grüße
Verfasst: Freitag 29. Januar 2010, 03:43
von snafu
Naja, da Zeichenketten in Python unveränderlich sind, würde ich einfach alles vom Original-String außer das letzte Zeichen mit dem gewünschten Zeichen kombinieren:
Wobei `-1` das letzte Zeichen / letzter Index ist und der Doppelpunkt bedeutet: Alles bis zu der-und-der Position.
Alternativ, wenn da z.B. eine `23` steht und die zu einer `5` gemacht werden soll (also unterschiedliche Länge und es kommt einfach auf die Zahl nach dem Bindestrich an):
Code: Alles auswählen
>>> s = '7-1-1544-1338-23'
>>> '-'.join(s.split('-')[:-1] + ['5'])
'7-1-1544-1338-5'
Letzteres ist allerdings schon wieder so umständlich, dass man dort tatsächlich eine Regexp in Erwägung ziehen könnte, sofern es was simples für diesen Fall gibt.
Verfasst: Freitag 29. Januar 2010, 10:46
von BlackJack
Wenn man Splitten und `re` vermeiden möchte, ginge noch das hier:
Code: Alles auswählen
In [14]: s = '7-1-1544-1338-23'
In [15]: s[:s.rindex('-') + 1] + '5'
Out[15]: '7-1-1544-1338-5'
Verfasst: Samstag 30. Januar 2010, 10:38
von mit
Danke hat prima funktioniert.
Ich habe noch diese strings:
name-class-Candidates01_vs_all_txt_output.txt
...
name-class-Candidates09_vs_all_txt_output.txt
name-class-Candidates10_vs_all_txt_output.txt
name-class-Candidates11_vs_all_txt_output.txt
....
Aus diesen strings würde ich ganze die Zahlen extrahiert bekommen, d.h.
aus 01 -> 1
aus 09 -> 9
aus 10 -> 10
Wie kann man dies am besten machen?
Verfasst: Samstag 30. Januar 2010, 10:46
von Dav1d
Eine Lösung mit 'ner regex
Code: Alles auswählen
>>> int(re.findall('[\d]+', 'name-class-Candidates09_vs_all_txt_output.txt')[0])
9
EDIT: noch was schönes ohne re,
Code: Alles auswählen
>>> int(''.join([i for i in 'name-class-Candidates09_vs_all_txt_output.txt' if i.isdigit()]))
9
Verfasst: Samstag 30. Januar 2010, 11:56
von sma
\d+ reicht. Die [] sind unnötig.
Die Lösung ohne re finde ich übrigens nicht schöner, da sie viel umständlicher ist und das Laufzeitverhalten definitiv schlechter sein wird.
Stefan
Verfasst: Samstag 30. Januar 2010, 14:20
von HWK
Da die Zahlen scheinbar immer zweistellig an derselben Stellen stehen, sollte auch das reichen:
Code: Alles auswählen
>>> s = 'name-class-Candidates01_vs_all_txt_output.txt'
>>> int(s[21:23])
1
Und noch eine Variante für das erste Problem:
Code: Alles auswählen
>>> s = '7-1-1544-1338-23'
>>> s.rsplit('-', 1)[0] + '-5'
'7-1-1544-1338-5'
MfG
HWK
Verfasst: Samstag 30. Januar 2010, 17:23
von BlackJack
Wobei das jetzt IMHO keine Aufgabe gewesen ist, die man nicht selbst lösen könnte, wenn man sich mit den Grunddatentypen von Python auskennt.
Verfasst: Samstag 30. Januar 2010, 17:42
von Defnull
BlackJack hat geschrieben:Wobei das jetzt IMHO keine Aufgabe gewesen ist, die man nicht selbst lösen könnte, wenn man sich mit den Grunddatentypen von Python auskennt.
Diese Frage-Mentalität häuft sich letzte Zeit, habe ich das Gefühl.
Verfasst: Samstag 30. Januar 2010, 17:47
von lunar
Defnull hat geschrieben:BlackJack hat geschrieben:Wobei das jetzt IMHO keine Aufgabe gewesen ist, die man nicht selbst lösen könnte, wenn man sich mit den Grunddatentypen von Python auskennt.
Diese Frage-Mentalität häuft sich letzte Zeit, habe ich das Gefühl.
Funktioniert ja auch super.
Verfasst: Samstag 30. Januar 2010, 19:24
von numerix
Defnull hat geschrieben:Diese Frage-Mentalität häuft sich letzte Zeit, habe ich das Gefühl.
Ich sehe da keine Veränderung - das war "immer" (= so lange ich dabei bin) so und wird sich aller Voraussicht nach auch nicht ändern, weil es genügend Menschen hier gibt, die bereitwillig die Arbeit derer machen, die schlicht zu faul sind, sich selbst Mühe zu machen ...
Verfasst: Samstag 30. Januar 2010, 23:27
von Leonidas
numerix hat geschrieben:Ich sehe da keine Veränderung - das war "immer" (= so lange ich dabei bin)
Nene, früher wurde der Poster (oftmals) hingewiesen wie man es löst, heutzutage werden meist Lösungen hingeklatscht. Ist etwas öde geworden.
Verfasst: Sonntag 31. Januar 2010, 07:13
von mit
Danke für die Lösungen.
Verfasst: Sonntag 31. Januar 2010, 12:20
von Defnull
OT: Wobei ich solche "Wie mach ich das am elegantesten" Wettbewerbe ja witzig finde

Und dabei lernt man auch ne Menge neues, z.B. das reduce() langsamer ist als ne einfache for-Schleife.
Verfasst: Sonntag 31. Januar 2010, 13:09
von snafu
Defnull hat geschrieben:z.B. das reduce() langsamer ist als ne einfache for-Schleife.
Allerdings.

Verfasst: Sonntag 31. Januar 2010, 13:12
von BlackJack
@Defnull: Gefährliches Halbwissen würde ich mal sagen. `reduce()` ist *immer* langsamer als eine ``for``-Schleife? Sollte man jetzt anhand *eines* Falls in Zukunft pauschal Entscheidungen über die Verwendung von `reduce()` vs. ``for``-Schleife treffen!?
Verfasst: Sonntag 31. Januar 2010, 21:18
von str1442
reduce() ist in Python 3.0 in Modules/_functoolsmodule.c definiert. Es benutzt den gleichen Mechanismus wie eine normale Python Forschleife (iter(), next() bis zur StopIteration (wobei die C Version auf NULL prüft)), nur eben in C. GET_ITER / FOR_ITER in ceval.c machen in etwa das Gleiche, nur mit Bytecode Sprüngen, es sollte also eigentlich nicht langsamer sein.
Verfasst: Sonntag 31. Januar 2010, 21:44
von Defnull
@str1442: reduce() wird dann langsamer, wenn das Erstellen der lambda-Funktion bzw. der Aufruf dieser den Vorteil durch die C-implementierte Schleife aufhebt. Da Funktionsaufrufe relativ teuer sind, kann dies bei einfachen Berechnungen durchaus der Fall sein, wie im anderen Thread bereits gezeigt.
@BlackJack: Ich habe weder von *immer* noch von einer Empfehlung für die Benutzung oder Vermeidung von reduce() gesprochen. Meine Aussage ist wahr für den Fall, auf den sie sich bezog.
Und die Entscheidung, ob man reduce() oder for-Schleifen verwendet, sollte eh nicht anhand minimaler Performance-Unterschiede (egal in welche Richtung), sondern über der Les- und Wartbarkeit entschieden werden. Von daher ist ein "reduce() ist schlecht" Halbwissen gar nicht mal so verkehrt.
Verfasst: Sonntag 31. Januar 2010, 23:51
von Darii
BlackJack hat geschrieben:@Defnull: Gefährliches Halbwissen würde ich mal sagen. `reduce()` ist *immer* langsamer als eine ``for``-Schleife?
reduce hat pro schleifendurchlauf zwangsläufig einen Funktionsaufruf mehr als for. Das macht es zwangsläufig langsamer als for. Da Python sowieso schon utopisch langsam ist, macht die Geschwindigkeit aber meist sowieso keinen Unterschied.
Verfasst: Sonntag 7. Februar 2010, 01:54
von mit
Ich habe folgende Regulär Expression geschrieben:
Code: Alles auswählen
pattern = r'[^\d-]'
a = "las|6-1-1643-1438-1"
print re.sub(pattern, '', a) # => 6-1-1643-1438-1
Dies funktioniert gut, aber gibt es eine andere re-methode um 6-1-1643-1438-1 auszuschneiden anstatt sub() zu benutzen?