Folgendes Problem:
ich hab einen String wie z.b. "du, bist du bist du bist du"
ich möchte aus "du" -> "ich" machen aber nur das zweite du! am besten unter angabe des index wo "du" anfängt. in diesem fall sprich String[9]
ps: re.sub("du","ich",string, count=X) funktioniert nicht, da es nur von links nach rechts zählt und man nicht auswählen kann!
Regular Expressions definierte Stelle (eine von3) ersetzen
Alternative:
String "du, bist du bist du bist du"
wenn ich weiß wo das 2te du anfängt, wie kann ich das 2te du RAUSSCHNEIDEN (ähnlich wie split) und den Rest als Liste mit 2 attributen zurückgeben?
dann könnte ich nachher einen neuen string erstellen indem ich die liste anzapfe und den gewünschten String in der mitte einführe.
Bin auch offen für jede andere lösung ,)
String "du, bist du bist du bist du"
wenn ich weiß wo das 2te du anfängt, wie kann ich das 2te du RAUSSCHNEIDEN (ähnlich wie split) und den Rest als Liste mit 2 attributen zurückgeben?
dann könnte ich nachher einen neuen string erstellen indem ich die liste anzapfe und den gewünschten String in der mitte einführe.
Bin auch offen für jede andere lösung ,)
Du kannst einen String durch das Suchwort splitten und die Teile anschließend wieder zusammenfügen, außer an der Stelle wo die Ersetzung vorgenommen werden soll.
Das geht bestimmt auch mit Regular Expressions, aber ich mag die nicht besonders.
Das geht bestimmt auch mit Regular Expressions, aber ich mag die nicht besonders.
Code: Alles auswählen
def mreplace(string, old, new, occurance):
splits = string.split(old)
if len(splits) < occurance:
raise ValueError("'%s' does not occures %i times in '%s'"
% (old, occurance, string))
return new.join((old.join(splits[0:occurance]),
old.join(splits[occurance:])))
a = "du, bist du bist du bist du"
print mreplace(a, "du", "ich", 2)
Zuletzt geändert von sparrow am Montag 10. September 2012, 18:56, insgesamt 1-mal geändert.
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Wie wäre es damit:
Code: Alles auswählen
def replace(s, word, repl):
pos = s.index(word, 1)
return "{}{}{}".format(s[:pos], repl, s[pos+len(word):])
replace(s, "du", "ich")
>>> 'du, bist ich bist du bist du'
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
Holla die Waldfee. Eigentlich hätte ich gedacht, dass Hyperions Lösung deutlich schneller ist, da ich ja erst den ganzen String splitte und ihn hinterher wieder zusammensetze. Aber
Bringt:
CPython 2.7.3
Code: Alles auswählen
import time
def mreplace(string, old, new, occurance):
splits = string.split(old)
if len(splits) < occurance:
raise ValueError("'%s' does not occures %i times in '%s'"
% (old, occurance, string))
return new.join((old.join(splits[0:occurance]),
old.join(splits[occurance:])))
def replace(s, word, repl):
pos = s.index(word, 1)
return "{}{}{}".format(s[:pos], repl, s[pos+len(word):])
a = "du, bist du bist du bist du"
start1 = time.time()
print mreplace(a, "du", "ich", 2)
stop1 = time.time()
start2 = time.time()
print replace(a, "du", "ich")
stop2 = time.time()
print stop1 - start1
print stop2 - start2Code: Alles auswählen
du, bist ich bist du bist du
du, bist ich bist du bist du
0.000127077102661
5.41210174561e-05- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Also zunächst einmal misst man solche Sachen mit dem `timeit`-Modul:
Das ergibt auf meinem alten System:
Also liege ich da knapp vor Dir. Ich benutze aber auch Python 3.2.
Ich weiß ja nicht, was Du aus Deinem Ergebnis heraus gelesen hast, aber 5.4 * 10 ^ -5 ist imho deutlich kleiner als 1.2 * 10 ^ -4
Insofern wundert mich das "aber" bei Dir...
Code: Alles auswählen
#!/usr/bin/env python
import time
def replace_sparrow(string, old, new, occurance=2):
splits = string.split(old)
if len(splits) < occurance:
raise ValueError("'%s' does not occure %i times in '%s'"
% (old, occurance, string))
return new.join((old.join(splits[0:occurance]),
old.join(splits[occurance:])))
def replace_hyperion(s, word, repl):
pos = s.index(word, 1)
return "{}{}{}".format(s[:pos], repl, s[pos+len(word):])
def main():
import timeit
a = "du, bist du bist du bist du"
for func in [replace_sparrow, replace_hyperion]:
t = timeit.Timer("{0}('{1}', '{2}', '{3}')".format(func.__name__, a,
"du", "ich"),
"from __main__ import {0}".format(func.__name__))
count = 10000000
print(func.__name__, (t.timeit(count) / count))
if __name__ == "__main__":
main()
Code: Alles auswählen
replace_sparrow 3.6277180910110475e-06
replace_hyperion 3.4617495059967042e-06
./replace.py 69,86s user 0,01s system 98% cpu 1:11,01 total
Ich weiß ja nicht, was Du aus Deinem Ergebnis heraus gelesen hast, aber 5.4 * 10 ^ -5 ist imho deutlich kleiner als 1.2 * 10 ^ -4
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
Ah shit, die Zahl vor dem Komma hat mich so verwirrt, dass ich das Ende gar nicht mehr angeschaut habe.Hyperion hat geschrieben:Ich weiß ja nicht, was Du aus Deinem Ergebnis heraus gelesen hast, aber 5.4 * 10 ^ -5 ist imho deutlich kleiner als 1.2 * 10 ^ -4Insofern wundert mich das "aber" bei Dir...
Gut, dann ist mein Weltbild jetzt ja wieder gerade
Code: Alles auswählen
import re
def replace(string, word, repl, place):
posl=[]
for match in re.finditer(word, string):
posl.append(match.start())
pos=posl[place-1]
return "{}{}{}".format(string[:pos], repl, string[pos+len(word):])Nun wird es aber echt Zeit für eine List Comprehension:
oder mittels map:
Auch solltest du mal richtige Namen in betracht ziehen. "string" (was auch noch einen eingebauten Typen verdeckt) "repl", "place" und "pos1" sind alle sehr nichtssagend.
Die start-Methode würde ich auch nicht auf jedem item aufrufen, dass reicht ja im prinzip bei ``pos1[place-1].start()``.
Und das Erstellen der Liste kann man eigentlich auch sparen:
Code: Alles auswählen
pos1 = [match.start() for match in re.finditer(word, string)]Code: Alles auswählen
pos1 = map(operator.methodcaller("start"), re.finditer(word, string))Die start-Methode würde ich auch nicht auf jedem item aufrufen, dass reicht ja im prinzip bei ``pos1[place-1].start()``.
Und das Erstellen der Liste kann man eigentlich auch sparen:
Code: Alles auswählen
pos = next(itertools.islice(re.finditer(word, string), place-1, place)).start()Das Leben ist wie ein Tennisball.
Vielen Dank, werde drüber nachdenken.
Nehmen wir an ich habe folgenden String
'[H]C(=O)CCC1=C(CC)C=C(CCCC)C(CC(=O)OC)=C1C'
es handelt sich um ein molekül im .smiles format.
Ich muss wissen wie weit die carbonylgruppen voneinander entfernt sind: C(=O)
Das Problem ist immer wenn klammern kommen wie zb, C1=C(CC)C hier, dann darf (CC) nicht mitgezählt werden, da es sich um eine verzweigung handelt und nicht zum direkten weg der carbonylgruppen beiträgt.
Allerdings taucht die zweite carbonylgruppe (eher carboxy, aber das sei jetzt mal egal) innerhalb von klammern auf, das macht aber nichts, da der weg ja trotzdem vorhanden ist. Im grunde lässt sich die smiles zeile in folgendes umschreiben:
'[H]C(=O)CCC1=C(CC)C=C(CCCC)C(=C1C)CC(=O)OC'
Nehmen wir an ich habe folgenden String
'[H]C(=O)CCC1=C(CC)C=C(CCCC)C(CC(=O)OC)=C1C'
es handelt sich um ein molekül im .smiles format.
Ich muss wissen wie weit die carbonylgruppen voneinander entfernt sind: C(=O)
Das Problem ist immer wenn klammern kommen wie zb, C1=C(CC)C hier, dann darf (CC) nicht mitgezählt werden, da es sich um eine verzweigung handelt und nicht zum direkten weg der carbonylgruppen beiträgt.
Allerdings taucht die zweite carbonylgruppe (eher carboxy, aber das sei jetzt mal egal) innerhalb von klammern auf, das macht aber nichts, da der weg ja trotzdem vorhanden ist. Im grunde lässt sich die smiles zeile in folgendes umschreiben:
'[H]C(=O)CCC1=C(CC)C=C(CCCC)C(=C1C)CC(=O)OC'
Und das ist der Grund, warum man in seine Problembeschreibung immer das "große Problem" hineinschreibt. Da beliebig tiefe Verschachtelungen möglich sind, kannst du das nicht mehr mit regulären Ausdrücken lösen, dafür brauchst du einen, wenn auch sehr trivialen, Parser. Noch einfacher ist das Problem aber, wenn du einfach mal nach "python smiles" suchst, es existieren dazu nämlich schon fertige Bibliotheken.
Das Leben ist wie ein Tennisball.
Nur um die Tokens zu extrahieren. Nur mit regulären Ausdrücken sind beliebige Verschachtelungstiefen mathematisch nicht möglich.flummi hat geschrieben:schreibt man parser nicht mit regulären ausdrücken?
Das Leben ist wie ein Tennisball.
Code: Alles auswählen
sekura@sekura-GA-MA770-UD3:~/frowns$ python setup.py build
running build
running build_py
running build
running build_ext
my_init_posix: changing gcc to g++
building '_pysssr' extension
g++ -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -I/usr/include/python2.7 -c pysssr.cxx -o build/temp.linux-i686-2.7/pysssr.o
cc1plus: Warnung: Kommandozeilenoption »-Wstrict-prototypes« ist gültig für Ada/C/ObjC, aber nicht für C++ [standardmäßig aktiviert]
pysssr.cxx:5:20: schwerwiegender Fehler: Python.h: Datei oder Verzeichnis nicht gefunden
Kompilierung beendet.
error: command 'g++' failed with exit status 1
under windows and linux/macosx using gcc 3.0 or higher.
sudo apt-get install gcc -->> gcc ist schon die aktuellste version
was muss ich machen? bzw. was funktioniert hier nicht?
Warum schaust du in die Readme, wenn die Fehlermeldung dort ganz eindeutig steht?
Wahrscheinlich fehlt bei dir einfach nur das python-dev Paket oder der dazugehörige Include-Pfad. Hast du mal geschaut, ob du das Projekt (welches auch immer) wirklich selber kompilieren musst und ob es nicht vielleicht schon im Paketmanager steckt?pysssr.cxx:5:20: schwerwiegender Fehler: Python.h: Datei oder Verzeichnis nicht gefunden
Das Leben ist wie ein Tennisball.
Also in der readme stand ich soll das so eingeben ;P
wie schau ich denn nach "ob es schon im packetmanager steckt". ja das ist bestimmt ne doofe frage aber ich hab linux seit 2 wochen drauf, und hab einiges aufzuholen ...
was passiert denn genau beim compilen?
da wird aus textdateien eine binary geschrieben oder nicht? Unter windows dann text -> .exe.
unter linux wird aus textdatei eine shell geschrieben die auch eine textdatei ist?!
also falls du sowas wie das ubuntu software center meinst, da liefert "frowns" keinen treffer.
wie schau ich denn nach "ob es schon im packetmanager steckt". ja das ist bestimmt ne doofe frage aber ich hab linux seit 2 wochen drauf, und hab einiges aufzuholen ...
was passiert denn genau beim compilen?
da wird aus textdateien eine binary geschrieben oder nicht? Unter windows dann text -> .exe.
unter linux wird aus textdatei eine shell geschrieben die auch eine textdatei ist?!
also falls du sowas wie das ubuntu software center meinst, da liefert "frowns" keinen treffer.
