Listen und .remove Methode

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
bremer
User
Beiträge: 109
Registriert: Sonntag 25. Mai 2008, 00:13

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?
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

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.
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

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
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

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))
bremer
User
Beiträge: 109
Registriert: Sonntag 25. Mai 2008, 00:13

Ja, ich hatte set ganz vergessen.
Antworten