String modifizieren

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.
mit
User
Beiträge: 285
Registriert: Dienstag 16. September 2008, 10:00

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

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:

Code: Alles auswählen

>>> s = 'bla'
>>> s[:-1] + 'i'
'bli'
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.
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'
mit
User
Beiträge: 285
Registriert: Dienstag 16. September 2008, 10:00

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?
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

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
the more they change the more they stay the same
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

\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
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

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
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.
Benutzeravatar
Defnull
User
Beiträge: 778
Registriert: Donnerstag 18. Juni 2009, 22:09
Wohnort: Göttingen
Kontaktdaten:

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.
Bottle: Micro Web Framework + Development Blog
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.
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

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 ...
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
mit
User
Beiträge: 285
Registriert: Dienstag 16. September 2008, 10:00

Danke für die Lösungen.
Benutzeravatar
Defnull
User
Beiträge: 778
Registriert: Donnerstag 18. Juni 2009, 22:09
Wohnort: Göttingen
Kontaktdaten:

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.
Bottle: Micro Web Framework + Development Blog
Benutzeravatar
snafu
User
Beiträge: 6881
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Defnull hat geschrieben:z.B. das reduce() langsamer ist als ne einfache for-Schleife.
Allerdings. :D
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!?
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

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.
Benutzeravatar
Defnull
User
Beiträge: 778
Registriert: Donnerstag 18. Juni 2009, 22:09
Wohnort: Göttingen
Kontaktdaten:

@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.
Bottle: Micro Web Framework + Development Blog
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

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.
mit
User
Beiträge: 285
Registriert: Dienstag 16. September 2008, 10:00

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?
Antworten