Seite 1 von 1

Probleme mit Unicode-Objekt

Verfasst: Donnerstag 19. März 2009, 16:38
von Maikell
Hallo zusammen!

Habe folgendes Problem:

Ich habe eine (UTF-16 codierte) Liste (im Beispiel "textdatei" genannt). Jedes Element dieser Liste enhält einen Textabschnitt. Ich möchte nun aus dieser Liste alle Satzzeichen entfernen. Normalerweise würde ich das so machen:

Code: Alles auswählen

       

    def __init__(self, textdatei):

        normalized = textdatei
        i = 0
        while i < len(textdatei):
            if textdatei[i] == ".":
                print "Punkt erkannt! Lösche Punkt!"
                self.normalized[i] = " "
            i = i + 1

allerdings erhalte ich dann den Fehler:

TypeError: 'unicode' object does not support item assignment

Dann habe ich noch folgendes probiert:

Code: Alles auswählen

       

    def __init__(self, textdatei):

        normalized = textdatei
        i = 0
        while i < len(textdatei):
            if textdatei[i] == ".":
                print "Punkt erkannt! Lösche Punkt!"
                del self.normalized[i]
            i = i + 1

aber da motzt er:

TypeError: 'unicode' object doesn't support item deletion


Frage:
Wie kann ich aus dieser Unicode-Liste ("textdatei") die Punkte löschen?

Hoffe Ihr könnt mir helfen! Vielen Dank schonmal!

Grüße
Maikell

Verfasst: Donnerstag 19. März 2009, 16:43
von Rebecca
Strings und Unicore-Objekte sind unveraenderbar. Nutze replace:

Code: Alles auswählen

>>> s = u"hallo.welt"
>>> s.replace(".", "")
u'hallowelt'
Da ersparst du dir auch die Schleife, da du damit alle Punkte gleichzeitig ersetzen kannst. Mal davon abesehen, dass diese while-Konstrukt und das Index-Hochzaehlen eh nicht schoen ist...

Re: Probleme mit Unicode-Objekt

Verfasst: Donnerstag 19. März 2009, 16:53
von Darii
Maikell hat geschrieben:Habe folgendes Problem:

Ich habe eine (UTF-16 codierte) Liste (im Beispiel "textdatei" genannt). Jedes Element dieser Liste enhält einen Textabschnitt. Ich möchte nun aus dieser Liste alle Satzzeichen entfernen. Normalerweise würde ich das so machen:
Dein Problem ist, dass du keine Liste hast, sondern ein Unicode-String. Die sind in Python unveränderlich. Wenn du wirklich eine Liste haben möchtest, musst du das Objekt auch explizit in eine Liste umwandeln.

Code: Alles auswählen

normalized = list(textdatei)

Verfasst: Donnerstag 19. März 2009, 17:21
von Maikell
Danke!

Verfasst: Donnerstag 19. März 2009, 18:35
von Maikell
Noch ein Problem:

Ich komme mit diesen Unicode Objekten einfach nicht richtig klar :(

Ich habe einen Text gegeben. ("text") es ist eine deutsche Geschichte, also mit deutschen Wörtern. Die Satzzeichen sind schon entfernt, und es sind nur Kleinbuchstaben!

Dann habe ich eine Liste mit deutschen Stop-Wörtern ("stopwords"), ebenfalls utf16 codiert.

Was ich nun machen möchte:

Ich möchte ein Dictionary erstellen, indem alle Wörter des Textes vorkommen.
Der Key des Dictionaries soll das jeweilige Wort sein, der Value die Anzahl des Wortes im Text.
Allerdings sollen die Stopworte (also alle Worte in der Liste "stopwords") nicht im dictionary erscheinen!

Was ich bisher habe:

Code: Alles auswählen

        text = text.split()
        wordlist = {}
        i = 0
        stoplength = len(stopwords)
        textlength = len(text)
        while i < textlength:
                k = 0

                while k < stoplength:
                        if text[i]==stopwords[k]:
                                print "Stopwort gefunden!",text[i],"ist ein Stoppwort!"
                                del text[i]
                        k = k + 1
                if text[i] in wordlist:
                        print i, "ter Durchlauf.", text[i], "ist schon im Woerterbuch drin"
                        j = wordlist[text[i]]
                        newentry = {text[i] : j+1}
                        wordlist.update(newentry)
                        i = i + 1
                else:
                        newentry = {text[i] : 1}
                        wordlist.update(newentry)
                        i = i + 1
        print wordlist    
        print stopwords
        print text           
Das Dictionary wird erstellt und die Anzahl der Worte steht als Value auch dabei. So weit so gut!

erstes Problem: In den if-Block wo die Stopwörter erkannt werden sollten geht er nie rein! Die Stopworte landen ebenfalls im Dictionary!

zweites Problem:
Die Wörter mit Umlauten stehen nicht richtig da! z.b. heißt es statt "schürze" u'sch\xfcrze'

print dictionary gibt folgendes aus:
{u'dirne': 1, u'stehen': 1, u'ganz': 1, u'schnupperte': 1, u'w\xfcrste': 1, u'trog': 3, u'sollte': 1, u'sch\xfcrze': 1, u'nu\xdfhecken': 1, u'totfiel': 1, u'rutschte': 1, usw... }

print stopwords:
[u'\ufeffaber\r', u'alle\r', u'allen\r', u'alles\r', u'als\r', u'also\r', u'andere\r', u'anderem\r', u'anderer\r', usw...


genau der Selbe Quelltext hat bei einem englischen Text (also nicht utf16 codiert) übrigens wunderbar funktioniert!


Hoffe Ihr könnt mir nochmals einen Tipp geben wie ich das Problem lösen kann

Verfasst: Donnerstag 19. März 2009, 18:45
von cofi
Das ist schon richtig

Code: Alles auswählen

In [2]: print u'sch\xfcrze'
------> print(u'sch\xfcrze')
schürze
Ich glaube du solltest aber mal deinen Ansatz überdenken.

Beispielsweise kannst du deine `stopwords' als set nutzen und einfach auf Membership testen (und dann halt löschen)

Dazu kommt, das deine Wörter eh eine Liste sind. => Iteriere mit `for' direkt über die Liste.

Wenn du deine Wörter zählst, dann benutze `defaultdict' statt eines normalen.

Verfasst: Donnerstag 19. März 2009, 19:25
von BlackJack
@Maikell: Schau Dir doch die Stopworte noch einmal genau an. Die haben alle einen "Wagenrücklauf" als letztes Zeichen.

So grundsätzlich hat das gezeigte Stück Quelltext übrigens nichts mit Kodierungen zu tun, denn da scheint alles schon als Unicode-Objekte vorzuliegen.

Die ``while``-Schleife funktioniert noch aus einem anderen Grund nicht richtig: Wenn Du etwas aus `text` löschst, verschiebt sich der ganze Inhalt *danach* um eine Position nach vorne. Wenn die Stoppworte aus `text` gefiltert werden sollen, wäre es einfacher zum Beispiel mittels einer "list comprehension" eine neue Liste zu erstellen.

Der Name `wordlist` für ein Dictionary ist etwas irreführend.

Wenn etwas in beiden Zweigen einer ``if``/``else``-Abfrage passiert, kann man das auch *einmal* danach hinschreiben. Aber wie schon gesagt wurde: Lass das mit den ``while``-Schleifen und den Indexen und verwende eine ``for``-Schleife direkt über die Elemente.

Verfasst: Montag 23. März 2009, 14:44
von Maikell
stopwords ist eine utf16 codierte Liste mit deutschen Stopworten
wordlist ist ein Dictionary das als key ein Wort enthält und als value die jeweilige Anzahl der Worte wie oft sie in einem Text vorkommen.

In der "stopwords"-Liste stehen Worte, die auch im Dictionary stehen!

Wenn ich jetzt folgenden Code ausführe, dann sollte doch für jedes Stopwort (ca 300 sind in der Liste) dass auch im Dictionary ist, der code im if-block ausgeführt werden! (nämlich print "blubb")
Aber es passiert rein gar nichts!!
Er geht einfach nicht in den If Block rein! WARUM? Wo ist mein Denkfehler?

Hoffe Ihr könnt mir wieder helfen!

Code: Alles auswählen

        for j in stopwords:
            if j in wordlist:
                print "blubb!"   



Als Beispiel dafür, dass die gleichen Worte in beiden Objekten enthalten sind:

print wordlist liefert:

{u'dirne': 1, u'stehen': 1, u'ganz': 1, u'schnupperte': 1, u'w\xfcrste': 1, u'trog': 3, u'sollte': 1, u'sch\xfcrze': 1, u'nu\xdfhecken': 1, u'totfiel': 1,......

print stopwords liefert:
[u'\ufeffaber\r', u'alle\r', u'allen\r', u'alles\r', u'als\r', u'also\r', u'andere\r', u'anderem\r', u'anderer\r', u'anderes\r', u'anders\r', u'auch\r', u'auf\r', u'aus\r', [...] ,u'solcher\r', u'solches\r', u'soll\r', u'sollen\r', u'sollte\r', u'sollten\r', u'somit\r',usw...

Verfasst: Montag 23. März 2009, 15:41
von b.esser-wisser
Wird die Datei mit den 'Stopwords' unter windows erstellt und soll unter linux gelesen werden ? (Würde die "\r"s erklären).
Das "\r" am Ende musst du wohl irgendwie loswerden, z.B. in dem du die Datei mit "open("stopwords.txt", "rU")" - das U steht für "universal-newline-support" - öffnest, oder mit

Code: Alles auswählen

stopwords = [word.rstrip() for word in stopwords]
#set() wurde auch schon angesprochen:
# stopwords = set(word.rstrip() for word in stopwords)
hth, Jörg
ps.:
stopwords ist eine utf16 codierte Liste mit deutschen Stopworten
ist natürlich falsch
stopwords ist eine liste von unicode-objecten (Die sind nicht codiert).