Seite 1 von 1
re.sub
Verfasst: Mittwoch 21. Januar 2004, 14:05
von HarryH
Hallo,
Geht das auch schneller oder besser?
Code: Alles auswählen
import re
s="C:\Dokumente und Einstellungen\All Users\Dokumente\Hinz+Kunz"
for i,j in zip([" ",r"\\","\+"],["_",r"\\\\","-"]):s=re.sub(i,j,s)
print s
Würde mich über Anregungen freuen. Danke
Re: re.sub
Verfasst: Mittwoch 21. Januar 2004, 14:39
von Voges
Hallo!
HarryH hat geschrieben:Code: Alles auswählen
s="C:\Dokumente und Einstellungen\All Users\Dokumente\Hinz+Kunz"
Dass das für Python eine korrektes String-Literal ist, finde ich eigenwillig. Bei Compilern/Interpretern anderer Sprachen wird man zumindest mit einem Warning darauf aufmerksam gemacht, dass es die Escape-Sequenzen \D, \A und \H nicht gibt.
Mein Vorschlag für die Ersetzung:
for t in ((" ","_"),("","\\"),("+","-")): s = s.replace(*t)
Jan
Verfasst: Mittwoch 21. Januar 2004, 15:10
von Dookie
Hallo HarryH,
Mein Vorschlag wäre
Code: Alles auswählen
s="C:\Dokumente und Einstellungen\All Users\Dokumente\Hinz+Kunz"
replacedict = {" ":"_", "\\":"\\\\", "+":"-"}
s = "".join(map(lambda x: rd.get(x,x), s))
Bei Python2.3 kannst Du die letzte Zeile auch durch
ersetzen.
Welche version schnelle ist müsste man testen.
Gruß
Dookie
re:
Verfasst: Mittwoch 21. Januar 2004, 15:26
von HarryH
Hallo Dookie, Jan
Ich habe mal ausprobiert was am schnellsten geht.
Code: Alles auswählen
import re
from time import *
zeit1=clock()
s=100000*"C:\Dokumente und Einstellungen\All Users\Dokumente\Hinz+Kunz"
for i,j in zip([" ",r"\\","\+"],["_",r"\\\\","-"]):s=re.sub(i,j,s)
zeit2=clock()
erg=zeit2-zeit1
print "1.Beispiel: Laufzeit = %.3f Sekunden" % erg
zeit1=clock()
s=100000*"C:\Dokumente und Einstellungen\All Users\Dokumente\Hinz+Kunz"
for t in ((" ","_"),("\\","\\\\"),("+","-")): s = s.replace(*t)
zeit2=clock()
erg=zeit2-zeit1
print "2.Beispiel: Laufzeit = %.3f Sekunden" % erg
zeit1=clock()
s=100000*"C:\Dokumente und Einstellungen\All Users\Dokumente\Hinz+Kunz"
rd = {" ":"_", "\\":"\\\\", "+":"-"}
s = "".join(map(lambda x: rd.get(x,x), s))
zeit2=clock()
erg=zeit2-zeit1
print "3.Beispiel: Laufzeit = %.3f Sekunden" % erg
Ausgabe:
1.Beispiel: Laufzeit = 0.920 Sekunden
2.Beispiel: Laufzeit = 0.324 Sekunden
3.Beispiel: Laufzeit = 5.833 Sekunden
Somit ist die Lösung von Jan die schnellste.
Dookie, ich habe die Variable "replacedict" in "rd" umgeschrieben, da du sie in deinem Beispiel später auch als "rd" verwendet hast.
Verfasst: Mittwoch 21. Januar 2004, 17:03
von Dookie
das kommt davon, wenn man im letzten momoent noch was ändert
folgende Methode dürfte wohl die schnellste Variante sein:
Code: Alles auswählen
s=100000*"C:\Dokumente und Einstellungen\All Users\Dokumente\Hinz+Kunz"
s = s.replace(" ", "_")
s = s.replace("\\", "\\\\")
s = s.replace("+", "-")
die ist interessanterweise schneller als folgende:
Code: Alles auswählen
s=100000*"C:\Dokumente und Einstellungen\All Users\Dokumente\Hinz+Kunz"
s = s.replace(" ", "_").replace("\\", "\\\\").replace("+", "-")
Gruß
Dookie
Verfasst: Mittwoch 21. Januar 2004, 17:31
von Voges
Hallo!
Dookie hat geschrieben:folgende Methode dürfte wohl die schnellste Variante sein:
Kann ich nicht bestätigen.
Code: Alles auswählen
from time import *
for _ in range(10):
zeit1=clock()
s=100000*"C:\Dokumente und Einstellungen\All Users\Dokumente\Hinz+Kunz"
s = s.replace(" ", "_")
s = s.replace("\", "\\\")
s = s.replace("+", "-")
zeit2=clock()
erg=zeit2-zeit1
laufzeit = "%.3f / " % erg
zeit1=clock()
s=100000*"C:\Dokumente und Einstellungen\All Users\Dokumente\Hinz+Kunz"
for t in ((" ","_"),("\","\\\"),("+","-")): s = s.replace(*t)
zeit2=clock()
erg=zeit2-zeit1
laufzeit += "%.3f / " % erg
zeit1=clock()
s=100000*"C:\Dokumente und Einstellungen\All Users\Dokumente\Hinz+Kunz"
s = s.replace(" ", "_").replace("\", "\\\").replace("+", "-")
zeit2=clock()
erg=zeit2-zeit1
laufzeit += "%.3f" % erg
print laufzeit
Ausgabe:
0.295 / 0.303 / 0.301
0.302 / 0.299 / 0.301
0.305 / 0.300 / 0.298
0.304 / 0.301 / 0.301
0.305 / 0.298 / 0.300
0.307 / 0.299 / 0.297
0.304 / 0.298 / 0.301
0.303 / 0.299 / 0.301
0.301 / 0.299 / 0.299
0.303 / 0.303 / 0.298
Naja, tolle Unterschiede sind das nicht. Eher zufällig. Tatsächlich scheint es (auf meinem Rechner) so zu sein, dass die erste Methode in der For-Schleife die langsamste ist, unabhängig davon, welche von den dreien die erste ist.
Jan
Verfasst: Mittwoch 21. Januar 2004, 17:53
von Dookie
Ich hab jetzt mal das Beispiel so verändert, daß nicht ein megalanger String sonder 100000 "normallange" Strings bearbeitet werden. So werden die Unterschiede noch deutlicher.
Code: Alles auswählen
import re
from time import *
sl=100000*["C:\Dokumente und Einstellungen\All Users\Dokumente\Hinz+Kunz"]
zeit1=clock()
for s in sl:
for i,j in zip([" ",r"\\","\+"],["_",r"\\\\","-"]):s=re.sub(i,j,s)
zeit2=clock()
erg=zeit2-zeit1
print "1.Beispiel: Laufzeit = %.3f Sekunden" % erg
sl=100000*["C:\Dokumente und Einstellungen\All Users\Dokumente\Hinz+Kunz"]
zeit1=clock()
for s in sl:
for t in ((" ","_"),("\\","\\\\"),("+","-")): s = s.replace(*t)
zeit2=clock()
erg=zeit2-zeit1
print "2.Beispiel: Laufzeit = %.3f Sekunden" % erg
sl=100000*["C:\Dokumente und Einstellungen\All Users\Dokumente\Hinz+Kunz"]
zeit1=clock()
for s in sl:
s = s.replace(" ", "_").replace("\\", "\\\\").replace("+", "-")
zeit2=clock()
erg=zeit2-zeit1
print "3.Beispiel: Laufzeit = %.3f Sekunden" % erg
sl=100000*["C:\Dokumente und Einstellungen\All Users\Dokumente\Hinz+Kunz"]
zeit1=clock()
for s in sl:
s = s.replace(" ", "_")
s = s.replace("\\", "\\\\")
s = s.replace("+", "-")
zeit2=clock()
erg=zeit2-zeit1
print "4.Beispiel: Laufzeit = %.3f Sekunden" % erg
Ich hab mal drei Durchläufe rechnen lassen.
Code: Alles auswählen
fritz@seneca:~/Python/Beispiele$ python replacetest.py
1.Beispiel: Laufzeit = 9.250 Sekunden
2.Beispiel: Laufzeit = 1.510 Sekunden
3.Beispiel: Laufzeit = 1.120 Sekunden
4.Beispiel: Laufzeit = 1.170 Sekunden
fritz@seneca:~/Python/Beispiele$ python replacetest.py
1.Beispiel: Laufzeit = 10.020 Sekunden
2.Beispiel: Laufzeit = 1.570 Sekunden
3.Beispiel: Laufzeit = 1.200 Sekunden
4.Beispiel: Laufzeit = 1.250 Sekunden
fritz@seneca:~/Python/Beispiele$ python replacetest.py
1.Beispiel: Laufzeit = 9.740 Sekunden
2.Beispiel: Laufzeit = 1.590 Sekunden
3.Beispiel: Laufzeit = 1.190 Sekunden
4.Beispiel: Laufzeit = 1.280 Sekunden
Gruß
Dookie
Verfasst: Mittwoch 21. Januar 2004, 18:28
von Voges
Hallo!
Dookie hat geschrieben:Ich hab jetzt mal das Beispiel so verändert, daß nicht ein megalanger String sonder 100000 "normallange" Strings bearbeitet werden. So werden die Unterschiede noch deutlicher.
Das ist natürlich eine ganz andere Aufgabenstellung:
Im ersten Ansatz hast Du 3 replace()-Aufrufe versucht, zu optimieren, was bei einem String von 6 Mio. Zeichen erwartungsgemäß nichts bringt. Dass das jetzt im zweiten Ansatz bei 300000(!) replace()-Aufrufen (bei einem 60-Zeichen-String) ganz anders aussehen muss, ist klar. Also HarryH, nächstes Mal bitte eine klare Aufgabenstellung
Wichtig fände ich allerdings auch die "Universalität" einer Lösung. Drei fest kodierte replace()-Aufrufe sind weniger flexibel, als ein replace()-Aufruf, dessen Häufigkeit nur von der Länge eines Tuples oder einer Liste abhängt. Und ich sehe gerade gefordert war "schneller und
besser"
Code: Alles auswählen
tpls = ((" ","_"),("\","\\\"),("+","-"))
for s in sl:
for t in tpls: s = s.replace(*t)
Damit mach' ich noch ein paar Hundertstel gut. Aber an den Windabweisern und dem Heckspoiler muss ich noch basteln.
Jan
Nachtrag: An den Reifen lag's.Code: Alles auswählen
ttbl = string.maketrans(" +","_-")
for s in sl:
s = s.translate(ttbl)
s = s.replace("\", "\\\")
Superschnell und völlig un-universell.