Excel Sonderzeichen/Umlaute und Teilstring Problem

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
DerBorsti
User
Beiträge: 18
Registriert: Freitag 30. März 2012, 13:44

Hallo zusammen

ich bin absoluter python anfänger das vorweg :P

Ja ich weiss es gibt reichlich Lösungsansätze bezüglich meines Problems aber die gefundenen Lösungen beziehen sich auf xlsx oder win32com.client Klassen basierten Skripten.
Ich kann leider auf Grund der Aufgabenstellung keine zusätzlichen Klassen "downloaden" und verwenden.
also mein daten:

Excel Datei mit einem Tabellenblatt mit 6 Splaten mit Informationen über Postleitzahl,Adresse mit Hausnummer,Stadt,Stadtteil, Name => diese habe ich umgewandelt in Excel zu einer csv mit Leerzeichentrennung

Mein Quellcode soweit:

Code: Alles auswählen

# -*- coding: iso-8859-15 -*-
import csv

##reader = csv.DictReader(open("asd.csv", "rb"))

def csv_auslesen(Dateiname):
	reader = csv.reader(open(Dateiname, "rb") , delimiter=";")

	ort=[]
	postcode=[]
	strasse=[]
	ortsteil=[]
	country=[]
	name=[]
	for row in reader: 
		 ort.append( row[1])
		 postcode.append( row[0])
		 strasse.append( row[2])
		 ortsteil.append( row[3])
		 country.append( row[4])
		 name.append( row[5])



## Um Spaltennamen zulöschen
	del postcode[0]
	del ort[0]
	del strasse[0]
	del ortsteil[0]
	del country[0]
	del name[0]

##for a in strasse:
##	a.replace(unichr(252) ,"ue")
##	a.replace(unichr(246) ,"oe")

	return postcode,ort,strasse,ortsteil,country,name
Jetzt zu meinen konkreten Problemen samt Beispiel

Die Umlaute:
Ich habe Addressen sowohl mit "ö" "ä" als auch "ß" im Namen zb.: "Blöde Straße 4a" wie schaffe ich es das "ö" in ein oe zubekommen [oder es als "ö" zuspeichern] und dass "ß" zubehalten?
Grund ist dass ich die Ausgelesenen Daten dann wieder rum weiterreichen will und damit die Eindeutigkeit der Strasse / Straße bestehen bleibt muss ich halt diese Dinge mitschleppen
Ich habe es sowohl über # -*- coding: iso-8859-15 -*- als auch durch replace / search / match versucht aber bin gescheitert....


Teilstrings:
Meine Addressen beinhalten Informationen wie Hausnummer 112-114 ( Bsp.: "Blöde Straße 114-115") wie schaffe ich es nun nur die 114 als zahl rauszufiltern? ich habe schon geschafft nur die zahlen rauszufiltern

Code: Alles auswählen

hausnummer= filter(lambda x: x.isdigit(),strasse[i])
Ja ich weiss dass es auch Hausnummern wie 14a gibt aber dazu bin ich einfach noch zu unfähig auch die rauszuprogrammieren

Code: Alles auswählen

adresse = re.findall('(()?[a-zA-Z_]+)',strasse[i],re.IGNORECASE |re.UNICODE)
Problem: so bekomme ich auch das "a" von zb "Blöde Straße 14 a" :s

Ich bin für jedliche Verbesserung und Hilfe sehr dankbar!!!

Vielen Dank
BlackJack

@DerBorsti: Anmerkungen zum Code: Dateien sollte man auch explizit wieder schliessen. Am einfachsten und sichersten geht das mit der ``with``-Anweisung.

Die Daten in einer `row` gehören von der Bedeutung her zusammen, also sollte man sie nicht auf verschiedene Listen verteilen.

Statt die Kopfzeile am Anfang der Liste(n) zu löschen nachdem alles eingelesen ist, sollte man sie lieber gar nicht erst in die Liste(n) hinein tun. Einfach beim `reader` vor der Schleife einmal `next()` aufrufen und das Ergebnis — die Kopfzeile — ignorieren, ist die einfachere und effizientere Vorgehensweise.

Welche Python-Version setzt Du ein? Welchen Typ haben die Objekte in den Listen?

Schau mal in der Dokumentation was die `replace()`-Methode macht. Tipp: Zeichenketten sind unveränderbar.

Der Kodierungskommentar ist für den Compiler da, damit er weiss wie der *Quelltext* kodiert ist. Das hat keinen Einfluss auf irgend etwas anderes, insbesondere nicht auf Funktionen die Daten lesen oder schreiben. Wenn Du eingelesene Daten von Bytes in Zeichen dekodiert haben möchtest, musst Du das entweder selber explizit tun, oder zumindest den Funktionen die das für Dich machen könnten, konkret eine Kodierung angeben.

Das mit den Hausnummern solltest Du schnell wieder vergessen. Es gibt zum Beispiel auch Strassen die keinen Namen, sondern eine Nummer haben, Beispiel: „Strasse 42”. Oder Hausnummern die nicht eine einzige Ziffer enthalten.
DerBorsti
User
Beiträge: 18
Registriert: Freitag 30. März 2012, 13:44

BlackJack hat geschrieben:@DerBorsti: Anmerkungen zum Code: Dateien sollte man auch explizit wieder schliessen. Am einfachsten und sichersten geht das mit der ``with``-Anweisung.

Die Daten in einer `row` gehören von der Bedeutung her zusammen, also sollte man sie nicht auf verschiedene Listen verteilen.

Statt die Kopfzeile am Anfang der Liste(n) zu löschen nachdem alles eingelesen ist, sollte man sie lieber gar nicht erst in die Liste(n) hinein tun. Einfach beim `reader` vor der Schleife einmal `next()` aufrufen und das Ergebnis — die Kopfzeile — ignorieren, ist die einfachere und effizientere Vorgehensweise.

Welche Python-Version setzt Du ein? Welchen Typ haben die Objekte in den Listen?

Schau mal in der Dokumentation was die `replace()`-Methode macht. Tipp: Zeichenketten sind unveränderbar.

Der Kodierungskommentar ist für den Compiler da, damit er weiss wie der *Quelltext* kodiert ist. Das hat keinen Einfluss auf irgend etwas anderes, insbesondere nicht auf Funktionen die Daten lesen oder schreiben. Wenn Du eingelesene Daten von Bytes in Zeichen dekodiert haben möchtest, musst Du das entweder selber explizit tun, oder zumindest den Funktionen die das für Dich machen könnten, konkret eine Kodierung angeben.

Das mit den Hausnummern solltest Du schnell wieder vergessen. Es gibt zum Beispiel auch Strassen die keinen Namen, sondern eine Nummer haben, Beispiel: „Strasse 42”. Oder Hausnummern die nicht eine einzige Ziffer enthalten.
Vielen Dank für deinen Kommentar

"with" - Anweisung noch nie davon gehört :D -> wird nachgelesen !

Python version 2.6.5 ( programmiere aber in WinPython )

row - Zusammenhang = ist korrekt aber ich brauch die einzelnen Informationen seperat um sie so einfach in der Ausgabe umsortiert ausgeben zukönnen ( ist der vorstellunghalber für mich dann einfacher umzusetzen)

replace() - werde ich mir erneut zur gemüte ziehen !

Kodierung - mhh okay soweit wie ich das sehe nimmt der "csv.reader" eine Kodierung vor
csv tabelle : Sprötzer Weg 31a
csv.reader ausgabe: Spr\xf6tzer Weg 31a
Kenne aus Java und c++ Kenntnissen nur Dez. und Hex. Zeichen aber vielleicht sehe ich auch den Zusammenhang gerade nicht....unicode...

Naja ich kann es leider nicht vergessen da ich mich mit Georeferenzierung beschäftige und eine Strasse dann mal eben Strasse heissen kann :) aber nun gut vielleicht ist das auch zu hoch noch soll ja alles nur als raumspielen dienen
BlackJack

@DerBorsti: Du brauchst nicht den kompletten Beitrag zitieren — der steht doch direkt darüber im Original. ;-)

Du brauchst die Informationen einer `row` nicht separat, denn wenn Du sie für die Ausgabe umsortieren willst, dann willst Du da ja doch schon wieder alle haben die zusammen gehören, nur eben nicht mehr zusammen gespeichert sind. Was den Zugriff nicht einfacher, sondern umständlicher macht. Wenn Du Zeichenkettenformatierung mit der `format()`-Methode auf Zeichenketten verwendest, ist das umsortieren beim erstellen einer Zeichenkette auch kein Problem. Wenn man zusammengehörende Informationen in parallelen Datenstrukturen verwaltet, muss man umständlicher darauf zugreifen. Beispielsweise über einen sonst unnötigen Index oder in dem man die Daten dann doch wieder zusammenführt als wenn man sie nicht getrennt hätte. Ausserdem ist das manipulieren von Datensätzen aufwändiger und fehleranfälliger weil man immer aufpassen muss, dass die Einzelstrukturen „parallel” bleiben.

`csv.reader` nimmt keine (De)kodierung vor, sondern liefert `str`-Objekte, was keine Zeichen- sondern Byteketten sind. So wie sie in der Datei stehen. Wenn Du darauf operierst, müssen die Byteketten mit denen Du das verknüpfst, also zum Beispiel die Suchkriterien in Deinem Programmquelltext, in der gleichen Kodierung vorliegen wie die Daten, die Du verarbeiten willst, oder Du arbeitest mit echten Zeichen, also dem `unicode`-Typ. Dann musst Du in Deinem Programm `unicode`-Literale verwenden und die Daten von `csv.reader()` dekodieren.

Das was Du als „csv.reader ausgabe” bezeichnest ist sicher nur ein Ausschnitt, denn das sieht nach der `repr()`-Umwandlung eines `str`-Objektes aus, wie man es zum Beispiel bekommt, wenn man ein `list`-Objekt in eine Zeichenkette (`str`) umwandelt. Das Ergebnis von `repr()` ist für Programmierer gedacht, damit die *genau* sehen was in der Zeichenkette enthalten ist, ohne dass irgendeine Kodierung dazwischen Daten verfälscht oder verschluckt. Dass bedeutet, dass alle Bytewerte ausserhalb von darstellbarem ASCII durch Escapesequenzen dargestellt werden.
Antworten