100pro dumme Frage - Wörter nach dict-Regeln generieren...

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.
Antworten
kurzfragende
User
Beiträge: 2
Registriert: Mittwoch 15. April 2009, 06:19

Hey,

ich schreibe gerade etwas, wofür ich Wörter aus nicht-europäischen Zeichen transkribiert brauche (keine Angst, keine Encoding-Probleme). Die Regeln dafür sind in einem dict - einige Zeichen sind allerdings mehrdeutig.

In dem Fall will ich übergenerieren, also wenn ich Regeln habe wie

Code: Alles auswählen

words=["hallo","dodo"] #die wären halt jetzt z.B. hebräisch
replacements={"o":["i","e"],"d":["m","b"]}
soll es mir alle möglichen Transkriptionen geben, also
halli
halle
mimi
meme
mime
memi
bibi
...

Irgendwie steh ich komplett auf dem Schlauch... So im Prinzip ist meine nicht-machende Funktion:

Code: Alles auswählen

words=["hallo","dodo"]
replacements={"o":["i","e"],"d":["m","b"]}

def translate():
    for word in words:
        for key, values in replacements.items():
            if key in word:
                for value in values:
                    word=word.replace(key,value)
        print word
    
if __name__=="__main__":
    translate()
Klar, die gibt nur eine Übersetzung pro Wort. Das nervt mich gerade tierisch, Brett vorm Kopf... So schwer kann das doch nicht sein! :(
Rekursiv ? Aber wie?

Vielen vielen Dank für jeden Tipp!... Will endlich diese Wörter haben und weitermachen. :roll:
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

Das elegant selbst zu implementieren ist nicht so trivial, aber zum Glück gibt es itertools.product, benötigt python 2.6. In der Doku steht aber auch eine Beispiel-Implementierung dazu, die man stattdessen nehmen könnte.

Code: Alles auswählen

from itertools import product
words=["hallo","dodo"] 
replacements={"o":["i","e"],"d":["m","b"]}
for word in words:
    for transcript in product(*[replacements.get(char, char) for char in word]):
        print ''.join(transcript)
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

Statt der LC kannst du an der Stelle auch einen Generatorausdruck nehmen, einmal Liste erstellen weniger.
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

str1442 hat geschrieben:Statt der LC kannst du an der Stelle auch einen Generatorausdruck nehmen, einmal Liste erstellen weniger.
Nein, beachte das Sternchen vor der Liste.

Edit: Argh, ja irgendwie hab ich total verdrängt, dass man vor Generatorausdrücke ja auch Klammern schreiben darf. Ist bloß die Frage, was schneller ist, ich tippe mal auf die LC.
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

Doch :P

Code: Alles auswählen

In [1]: def f(*args, **kwargs):
   ...:     print args, kwargs
   ...:     
   ...:     

In [2]: f(*[i for i in xrange(10)])
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) {}

In [3]: f(*(i for i in xrange(10)))
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) {}
Ein Generator ist schließlich auch nur ne Sequenz

ADD: Ich würd gar nicht so sehr nach praktischen Gründen suchen. Man braucht die Liste nicht, also sollte man sie imho auch nicht erstellen, egal iwiefern da ein paar Nanosekunden mehr oder weniger bei anfallen - eben die Semantik des Codes beachten. Und zumindest hat ein Generator weniger Speicherverbrauch. Performance mag dagegen ausgeglichen sein, LC's sind ja sicherlich auch nicht unoptimiert.
kurzfragende
User
Beiträge: 2
Registriert: Mittwoch 15. April 2009, 06:19

Vielen Dank für den Hinweis mit itertools.product, egal ob mit oder ohne LC ;) . Perfekt!

Und war ein guter Tritt in den Hintern, jetzt hab ich mir endlich Py2.6 besorgt...
Antworten