[g]Zeile löschen, wenn sie mehrere Großbuchstaben beinhaltet

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
Kelhim
User
Beiträge: 16
Registriert: Donnerstag 17. Mai 2007, 13:18
Wohnort: Köln

Hallo erst einmal, ich bin noch ziemlich neu bei Python! Ich arbeite an einer Wortliste, dabei nimmt jedes Wort eine eigene Zeile in Anspruch. Also so z.B.:

Code: Alles auswählen

Dies
ist
eine
WortLiSte
Eines der Wörter ist nun falsch geschrieben, da ja zu viele Buchstaben großgeschrieben sind. Wie kann ich solche Zeilen, in der mehr als ein Großbuchstabe vorkommt, entfernen?

(Hintergrund: Das Skript liest alle Wörter aus einer Textdatei und muss dabei auch solche offensichtlichen Fehler entfernen können! - Suchfunktion und Suchmaschine haben mir nicht weitergeholfen. :( )

EDIT: Mein erster Ansatz war, alle Kombinationen zweier Großbuchstaben zu berechnen und jede neue Kombination dann sofort zu löschen. Das klappt auch wunderbar, nur das geht nicht immer auf, da ein Wort ja auch fünf Buchstaben haben kann statt 4 ---> dann bleibt ein Buchstabe übrig!
Zuletzt geändert von Kelhim am Freitag 18. Mai 2007, 22:15, insgesamt 1-mal geändert.
schlangenbeschwörer
User
Beiträge: 419
Registriert: Sonntag 3. September 2006, 15:11
Wohnort: in den weiten von NRW
Kontaktdaten:

Hi Kelhim, willkommen im Forum!
Wäre es nicht besser, solche Fehler zu verbessern, anstatt die Wörter zu löschen?
Mit "einstring".capitalize() kannst du den String so abändern, dass er mit einem Großbuchstaben beginnt und sonst nur Kleinbuchstaben enthält.
Das ist natürlich ein Problem, wenn kleinzuschreibende Wörter aus Versehen einen Großbuchstaben in der Mitte haben...
Um zu sehen, ob das Wort mehr als einen Großbuchstaben enthält, kannst du folgendes machen:

Code: Alles auswählen

thestring="EinWortAusDeinerListe"
if thestring.islower() or thestring.istitle():
    print "Maximal ein Großbuchstabe am Wortanfang"
    # rechne hier weiter
Gruß, jj
Kelhim
User
Beiträge: 16
Registriert: Donnerstag 17. Mai 2007, 13:18
Wohnort: Köln

Hm, dieselbe Idee hatte ich auch, aber ich scheitere irgendwie an der Umsetzung ...

Code: Alles auswählen

words = words.splitlines()

for line in words:
	if not line.islower() and not line.istitle():
		words.remove(line)

print words
Aber das klappt nicht, keins der Listenelemente wird gelöscht ... Kann mir jemand einen Hinweis darauf geben, was an der Schleife falsch ist? Oder wie man das Problem besser lösen könnte?
schlangenbeschwörer
User
Beiträge: 419
Registriert: Sonntag 3. September 2006, 15:11
Wohnort: in den weiten von NRW
Kontaktdaten:

versuchs mal mit "or" statt "and" :wink:
Kelhim
User
Beiträge: 16
Registriert: Donnerstag 17. Mai 2007, 13:18
Wohnort: Köln

Warum denn "or"? Das würde doch dann heißen, dass er das Element auch dann löschen darf, wenn es völlig kleingeschrieben ist (dafür wäre es ja nicht title) oder wenn es title ist (dafür aber nicht kleingeschrieben) --> also dürfte er 'Sssssss' löschen, weil es ja eine der beiden Bedingungen erfüllt ... oder nicht? Mit "and" sollte er beide Bedingungen berücksichtigen ... (hoffe, ich versteh das jetzt auch richtig :lol: )

Das Ergebnis ist aber so oder so dasselbe, die ungewünschten Wörter in der Liste bleiben ... So sieht mein Modell aus:

Code: Alles auswählen

words = '''
AAAAA
aaaaaAAaaa
Aaaaa
'''

words = words.splitlines()
print words
for line in words:
    if not line.islower() or not line.istitle():
        words.remove(line)

print words
Das Lustige ist, dass er zwar Einträge löscht ... aber welche, das hängt davon ab, wie ich die Wörter im String words anordne ... irgendwas mache ich da komplett falsch! ^^
BlackJack

Du entfernst Elemente aus einer Liste über die Du gerade in der Schleife läufst, das macht Probleme weil durch das entfernen alle folgenden Elemente nach vorne rücken und in der Schleife dann Elemente ausgelassen werden. Ausserdem ist es ineffizient weil `remove()` die Liste wieder von vorne durchgeht, bis das Element gefunden wurde. Normalerweise ist es besser eine neue Liste zu erstellen ohne die unerwünschten Elemente.

Code: Alles auswählen

In [64]: words
Out[64]: ['AAAAA', 'aaaaaAAaaa', 'Aaaaa']

In [65]: [w for w in words if w.islower() or w.istitle()]
Out[65]: ['Aaaaa']
Kelhim
User
Beiträge: 16
Registriert: Donnerstag 17. Mai 2007, 13:18
Wohnort: Köln

Wohoo, Blackjack, du hast mein Problem in einem Einzeiler gelöst! :o Danke, auf den Haken mit dem Löschen innerhalb der Schleife wäre ich echt nie gekommen, obwohl's so nahe liegt ...
Kelhim
User
Beiträge: 16
Registriert: Donnerstag 17. Mai 2007, 13:18
Wohnort: Köln

Ich muss noch einmal nachhaken - dummerweise löscht das Skript auch Wörter, die mit einem Großbuchstaben beginnen und einen Umlaut beinhalten. Also zum Beispiel "Höhe". Dagegen sind Wörter wie "Österreich" oder "lösen" nicht betroffen.

Python behandelt also die deutschen Umlaute und das deutsche ß wie einen Großbuchstaben und löscht das Wort.

Wie kann ich das verhindern?
BlackJack

Wenn Du mit Zeichen statt mit Bytes arbeiten möchtest, solltest Du Unicode-Zeichenketten verwenden. Normale Zeichenketten sind einfach nur Bytes. Alle Werte aus dem ASCII-Bereich sind relativ eindeutig, aber was ausserhalb von ASCII liegt kann man nicht zuverlässig auf Eigenschaften wie Grossbuchstabe, oder auch nur Buchstabe im allgemeinen testen.
Kelhim
User
Beiträge: 16
Registriert: Donnerstag 17. Mai 2007, 13:18
Wohnort: Köln

Danke für den Hinweis! Ich hab es jetzt geschafft, mit unicode(string, 'latin-1') und dem codecs-Modul auch die Umlaute und hoffentlich auch die ß richtig zu unterscheiden, damit sie die Bedingungen erfüllen. :)

Hat zwar etwas gedauert und liest sich etwas durcheinander, aber es klappt so, wie es soll.
Antworten