Seite 1 von 1

Listen und .remove Methode

Verfasst: Sonntag 30. Oktober 2011, 02:16
von bremer
Ich versuche gerade mindestens zweifach vorkommenden Wörter zu eliminieren und der Computer zählt "sports" vier mal aber iteriert scheinbar nur einmal darüber und von daher kommt nur ein einzelnes Entfernen zu Stande. Vielleicht will er mir mitteilen, ich sollte mehr Sport treiben. Was meint ihr?

words.txt:

Code: Alles auswählen

offer is secret click secret link secret sports link play sports today went play sports secret sports event sport is today sport costs money

Code: Alles auswählen

# coding: utf-8
# Python 3.2

from re import split
file = open("words.txt")  # Enthält eine Liste von Wörtern, separiert durch \
                          # Leerzeichen. Keine Absätze enthalten.
content = file.read()
file.close()
words = split("\s", content)
for word in words:
    print(word, words.count(word))
    if words.count(word) > 1:
        words.remove(word)
        print(word, "entfernt.")
# Die Methode .remove entfernt nur ein einzelnes Wort.
print()
print(words)
Sollte der Codekopf eigentlich die Versionsnummer von Python enthalten? Und wozu dienen die -*- beim coding normalerweise?

Re: Listen und .remove Methode

Verfasst: Sonntag 30. Oktober 2011, 08:36
von Darii
bremer hat geschrieben:Vielleicht will er mir mitteilen, ich sollte mehr Sport treiben. Was meint ihr?
Keine Ahnung, ich kenne dich nicht, solltest du? ;)

Nein im Ernst ich vermute mal das es daran liegt, dass du die liste words veränderst, während du über sie iterierst. Das ist immer eine schlechte Idee. Am einfachsten ist es von hinten durch die Liste zu iterieren (for i in range(len(words)-1, -1, -1)). Oder die Verwendung von set() wenn dir die Reihenfolge nicht wichtig ist.
Sollte der Codekopf eigentlich die Versionsnummer von Python enthalten?
Ich mache das nie, aber schaden tut es sicherlich nicht.
Und wozu dienen die -*- beim coding normalerweise?
In Gedenken an emacs. Wenn du den nicht kennst/nicht verwendet vergiss einfach dass es -*- gibt. Unnützes Wissen.

Re: Listen und .remove Methode

Verfasst: Sonntag 30. Oktober 2011, 09:44
von sma
Die Grundregel ist: Ändere nie die Liste, über die du iterierst. Am einfachsten ist es, ein Kopie davon zu machen.

Ich würde allerdings den Algorithmus ändern. Der gezeigte Algorithmus hat durch count() eine Komplexität von O(N^2). Das ist schlechter als möglich. Statt aus einer Liste die doppelten Strings zu entfernen, schlage ich vor, in einer zweiten Liste das Ergebnis zu sammeln:

Code: Alles auswählen

seen = set()
keep = []
for word in words:
    if word not in seen:
        seen.add(word)
        keep.append(word)
print keep
Das liefert:

Code: Alles auswählen

['offer', 'is', 'secret', 'click', 'link', 'sports', 'play', 'today', 'went', 'event', 'sport', 'costs', 'money']
Stefan

Re: Listen und .remove Methode

Verfasst: Sonntag 30. Oktober 2011, 16:21
von /me
sma hat geschrieben:Ich würde allerdings den Algorithmus ändern.
Die Frage ist, was das Ziel des Algorithmus ist. Wenn es im Endeffekt nur darum geht doppelte Wörter zu eliminieren und die Reihenfolge keine Rolle spielt, dann geht es natürlich ganz einfach.

Code: Alles auswählen

words = list(set(words))

Re: Listen und .remove Methode

Verfasst: Sonntag 30. Oktober 2011, 16:49
von bremer
Ja, ich hatte set ganz vergessen.