string.replace mit dictionary

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.
nemomuk
User
Beiträge: 862
Registriert: Dienstag 6. November 2007, 21:49

string.replace mit dictionary

Beitragvon nemomuk » Donnerstag 21. Februar 2008, 16:09

Hallo,

wie kann ich in einem String einzelne "Sequenzen" mit Hilfe eines Dictionarys ersetzen?

Code: Alles auswählen

string = "kosidfmapofkpdsofpjosldlikddgoisdoijfpdsfoidsgpifdolikgzhpokfsigoifdgidomibfdgol"

dict = { "a":"b", "c":"d",....}
string.replace() #und die Schlüssel mit den zugehörigen Werten ersetzen...


Vielen Dank!
BlackJack

Beitragvon BlackJack » Donnerstag 21. Februar 2008, 16:16

Also wenn das immer ein Zeichen durch ein anderes ersetzen ist, dann schau Dir mal die `translate()`-Methode auf Zeichenketten an.
nemomuk
User
Beiträge: 862
Registriert: Dienstag 6. November 2007, 21:49

Beitragvon nemomuk » Donnerstag 21. Februar 2008, 16:22

Nein ist es nicht..., wenn ich dich richtig verstehe...

Ich will zum Beispiel sowas machen:

Code: Alles auswählen

dict = {

"qwe":"ert",
"fgh":"tzu",

}


Also völlig willkürlich und auch nicht jeden Buchstaben. Und so wie ich das bei translate verstanden habe, muss man da ein table haben mit 256 Zeichen... und alle Zeichen werden ersetzt
BlackJack

Beitragvon BlackJack » Donnerstag 21. Februar 2008, 17:35

Man könnte sich das mit `re.sub()` etwas basteln. Den regulären Ausdruck aus den Schlüsseln zusammensetzen und als Ersetzung dann eine Funktion, die aus dem Match-Objekt über das Dictionary die Übersetzung heraus sucht.
Benutzeravatar
mikrokosmos
User
Beiträge: 6
Registriert: Mittwoch 22. März 2006, 18:49

Beitragvon mikrokosmos » Donnerstag 21. Februar 2008, 17:55

Ich würde folgende Lösung vorschlagen:

Code: Alles auswählen

In [7]: text = "blubb"

In [8]: d = {"u": "a", "b": "p"}

In [9]: for i in d.iteritems():
   ...:     text = text.replace(*i)
   ...:

In [10]: text
Out[10]: 'plapp'
BlackJack

Beitragvon BlackJack » Donnerstag 21. Februar 2008, 18:04

Was die Gefahr birgt, dass eine Ersetzung die Zeichenkette so verändert, dass eine folgende Ersetzung zutrifft. Da Dictionaries ungeordnet sind, wäre das nicht einmal deterministisch. Ob diese Gefahr besteht, müsste SchneiderWeisse beantworten.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Beitragvon CM » Donnerstag 21. Februar 2008, 18:06

Das ist gefährlich, da
a) eine Reihenfolge in einem dict nicht sortiert ist und damit nicht unbedingt immer dieselbe Reihenfolge vorliegt (hängt natürlich vom Problem ab, ob sich das dict ggf. mal ändert oder nicht)
und b) weil es so zu multiplen Austauschen kommen kann - was vielleicht nicht erwünscht ist.

edit: Zu langsam ...
nemomuk
User
Beiträge: 862
Registriert: Dienstag 6. November 2007, 21:49

Beitragvon nemomuk » Donnerstag 21. Februar 2008, 18:10

ja, ich bin erst über pythonchallenge auf diese Frage gekommen und könnte das für ein Projekt gerbauchen...

Jetzt scheitert es ersteinmal hieran:

Code: Alles auswählen

a = ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z')
b = ('c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b')
stri = "g fmnc wms bgblr rpylqjyrc gr zw fylb. rfyrq ufyr amknsrcpq ypc dmp. bmgle gr gl zw fylb gq glcddgagclr ylb rfyr'q ufw rfgq rcvr gq qm jmle. sqgle qrpgle.kyicrpylq() gq pcamkkclbcb. lmu ynnjw ml rfc spj."
for x, y in zip(a,b):
   stri = stri.replace(x,y)
print stri


Das ganze gibt folgendes aus:
ababbababsbababababababababa etc.

Also nicht wirklich was ich will...

Was ist hieran falsch?

Danke für eure Hilfe!!!
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Beitragvon CM » Donnerstag 21. Februar 2008, 18:21

Du iterierst über Deine Austauspaare und ersetzt jeden Hit im String so lange bis nur noch 'a' und 'b' übrig bleiben.

Wenn Deine Schlüssel immer gleich lang sind, ließe sich auch über mit Schritten gleich der Länge des Schlüssels über den String iterieren. Dann kannst Du ggf. auch ein dict nutzen.

Gruß,
Christian
nemomuk
User
Beiträge: 862
Registriert: Dienstag 6. November 2007, 21:49

Beitragvon nemomuk » Donnerstag 21. Februar 2008, 21:52

für alle dies interessiert:

Code: Alles auswählen

import string
a = "abcdefghijklmnopqrstuvwxyz"
b = "cdefghijklmnopqrstuvwxyzab"
trans = string.maketrans(a,b)
stri = "g fmnc wms bgblr rpylqjyrc gr zw fylb. rfyrq ufyr amknsrcpq ypc dmp. bmgle gr gl zw fylb gq glcddgagclr ylb rfyr'q ufw rfgq rcvr gq qm jmle. sqgle qrpgle.kyicrpylq() gq pcamkkclbcb. lmu ynnjw ml rfc spj."
q = stri.translate(trans)
print q
a = raw_input()
Benutzeravatar
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Beitragvon mitsuhiko » Freitag 22. Februar 2008, 01:11

Code: Alles auswählen

import re

def replace_dict(string, replacements):
    regex = re.compile('|'.join(re.escape(a) for a in
                                sorted(replacements, lambda x: -len(x))))
    return regex.sub(lambda m: replacements[m.group(0)], string)


Ungetestet, sollte aber so hinhauen.
TUFKAB – the user formerly known as blackbird

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder