String mit line.split() "von hinten" einlesen

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
matlev
User
Beiträge: 5
Registriert: Montag 31. März 2008, 16:35
Wohnort: Berlin

Hallo liebe Forumsteilnehmer,

ich habe ein kleines Problem mit Python. Ich lese eine Datei zeilenweise ein und speichere deren Inhalt in mehreren Variablen, die ich dann entsprechend in eine DB einbaue:

Code: Alles auswählen

for line in file(myDBfile, "r"):
   try:
      [id, A, B, C, D, E, D1, D2] = line.split('\t')
      ....
Bei A bis E handelt es sich hierbei um Strings, D1 und D2 sind Datumseinträge.

Es handelt sich um sehr viele Einträge, und ab und an kriege ich eine Fehlermeldung (ValueError: Too many values to unpack). Ich habe herausgefunden, dass es daran liegt, dass String C dummerweise teilweise (wenn auch recht selten) selbst einen "\t" enthält.

Da ich mich eigentlich nur für A, B und E interessiere, dachte ich mir, dass es auch ausreichen würde, wenn ich die Einträge "von hinten" aufspalte, um an String E heranzukommen (in etwa so: [rest, E, D1, D2] = ???). Aber ich weiß leider nicht, wie man das anstellen kann. Könnte mir einer von euch vielleicht netterweise helfen?

Vielen Dank und viele Grüße!
Benutzeravatar
helduel
User
Beiträge: 300
Registriert: Montag 23. Juli 2007, 14:05
Wohnort: Laupheim

Moin,

Code: Alles auswählen

line.rsplit('\t', 3) 
Gruß,
Manuel
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Dann greif doch einfach über die Indizes drauf zu:

Code: Alles auswählen

lines = line.split()
A = lines[0]
B = lines[1]
E = lines[-3]
matlev
User
Beiträge: 5
Registriert: Montag 31. März 2008, 16:35
Wohnort: Berlin

Ähmm, ich habe das Gefühl, die Antwort war zu einfach, als dass die Frage es wert war, gestellt zu werden. :)

Vielen Dank jedenfalls, das hat wunderbar funktioniert und sehr geholfen!
matlev
User
Beiträge: 5
Registriert: Montag 31. März 2008, 16:35
Wohnort: Berlin

Ich hätte doch nochmals ne kurze Frage zu diesem Thema. Wie ich bereits im ersten Posting geschrieben habe, handelt es sich bei den Datensätzen D1 und D2 um Zeiteinträge. Diese liegen im folgenden Format vor:

YYYY-MM-DD HH:MM:SS (z.B. 2008-04-15 16:10:00)

Da String C in der Mitte auch beliebige Zeilensprünge beinhalten kann, und ich an A, B und E rankommen möchte, würde ich halt immer von vorne A und B lesen und von hinten E. Dazu müsste ich aber überprüfen, ob es sich bei dem letzten Eintrag in einer Zeile um ein String im Zeitformat (wie oben beschrieben) handelt. Also so etwas wie:
lines = line.split()
isTime(lines[-1])

Gibt es so eine Methode in Python? Ich konnte nichts genaues finden bisher. Oder wie würde man das über Pattern Matching machen? Ich bräuchte dann auch so etwas wie (isLong() oder isInt() für den ersten Eintrag "id" (lines[0]).
matlev
User
Beiträge: 5
Registriert: Montag 31. März 2008, 16:35
Wohnort: Berlin

Falls es irgend jemand interessieren sollte, ich habe es nun so gelöst:

Code: Alles auswählen

while (1):
         try:
            lastField = lines[-1]
            time.strptime(lastField, "%Y-%m-%d %H:%M:%S\n")
            lines = line.split('\t')
            break
         except Exception:
            line = f.next()
            lines = line.split('\t')
            line_count + 1
Zur Erklärung: Wenn das Format nicht übereinstimmt, dann bewirkt die Zeile
time.strptime(lastField, "%Y-%m-%d %H:%M:%S\n")
eine Exception. In dieser wird die nächste Zeile eingelesen und wieder geschaut, ob das Format im letzten Feld stimmt. Dies wird so lange gemacht, bis das Format das richtige ist.
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

matlev hat geschrieben:Da String C in der Mitte auch beliebige Zeilensprünge beinhalten kann
Ist der String denn in Delimiter eingefasst (Gaensefuesschen oder so)? Das csv-Modul kann naemlich mit solchen Strings gut umgehen und stoert sich nicht an Zeilenumbruechen. Dann haettest du das Datum immer in der gleichen Spalte.
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
matlev
User
Beiträge: 5
Registriert: Montag 31. März 2008, 16:35
Wohnort: Berlin

Na ja, das ist ja das Problem. Die Delimiter der Text-Datei, die ich in eine Datenbank einlesen möchte, sind Tabs (\t). Aber im mittleren String (C) kommen auch Tabs vor. Das ist bescheuert gespeichert, aber nun mal das was ich habe und daher muss ich probieren, es trotzdem korrekt einzulesen.

Mit dem Code, welchen ich vorher beschrieben habe, funktioniert es aber - soweit ich es bisher getestet habe - ganz gut.
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Nur nochmal zur Verdeutlichung: Das csv-Modul kommt problemlos mit sowas klar:

Code: Alles auswählen

111\t222\t"hallo\twelt"\t333
111\t222\t"hallo
welt"\t333
111\t222\t"hallo "bla" welt"\t333
Es hat kein Problem mit Delimitern im String, solange der String halt nochmal eigene Delimter hat (z.B. Gaensefuesschen).
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
Antworten