File mit readlines() auslesen, in Liste nach String suchen?

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
ivka_sto
User
Beiträge: 63
Registriert: Dienstag 11. Dezember 2007, 23:13

Samstag 21. März 2009, 14:45

Hallo allerseits,

Ich will in einem File Werte aktualisieren, dafür lese ich das File mittels readlines(), und, da es auch mehrere Stellen sind, finde ich die entsprechenden Stellen in der Liste mit .index(), und füge die neuen Werte ein:

Code: Alles auswählen


data = open('values.dat', 'r')
values = list()
values = data. readlines()
data.close()

data = open('new_values.txt', 'r')
new_values = list()
new_values = data. readlines()
data.close()

try:
   print 'in try'
   i = values.index('$ - next: values\n')
   print 'index: ' + i
   k = values.index('$ - end values\n')

   n = i + 1
   j = 0
   del values[n:k]

   while j < len(new_values):
      values.insert(n, new_values[j])
      j += 1
      n += 1

except:
   error = 3460

finally:
   ...

actual_data = open('values.dat', 'w')
ct = 0

while ct < len(values):
   actual_data.write(values[ct])
   ct += 1
   

Das hat auch bestens funktioniert, bevor ich auf das line.strip verzichtet habe, um das ursprüngliche feste Format der Daten zu behalten (feste Anzahl Zeichen pro Block). Was mich verwirrt ist, daß ich von den print-Markern das erste zurückbekomme (also in try), doch vom zweiten bekomme ich weder Text, noch Wert, also wird das try schon beim Versuch in der Liste zu suchen verlassen.

Übersehe ich etwas? Bestimmt .. wenn es jemandem auffällt, her mit den Vorschlägen :)

Danke schon mal.

Viele Grüße,
ivka_sto
Zuletzt geändert von ivka_sto am Samstag 21. März 2009, 15:35, insgesamt 2-mal geändert.
ivka_sto
User
Beiträge: 63
Registriert: Dienstag 11. Dezember 2007, 23:13

Samstag 21. März 2009, 14:52

Sorry für das doofe Code-Intend, ist wohl beim Copy und Paste durcheinandergegangen :(
Benutzeravatar
Hyperion
Moderator
Beiträge: 7472
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Samstag 21. März 2009, 14:54

Wie sollen wir dazu etwas sagen, ohne das Dateiformat zu kennen? (Beispiel posten!)

- Die Einrückungen sind kaputt!
- Du überschreibst das built-in file! Das solltest Du ändern.
- Man sollte Datei-Operationen mit with kapseln oder mit einem äquivalenten try... except... finally-Konstrukt:
- Das Iterieren über die einzelnen Zeilen ist nicht nötig!

Code: Alles auswählen

with open("filename") as data:
    values = data.readlines()
- Man sollte allgemeine Exception abfangen! (Worauf genau reagierst Du denn da überhaupt? error=4386 klingt auch kryptisch!)

So kann Dir im Moment niemand konstruktiv helfen.
ivka_sto
User
Beiträge: 63
Registriert: Dienstag 11. Dezember 2007, 23:13

Samstag 21. März 2009, 15:19

Es sind einfache .txt-Files, in denen zeilenweise Werte gespeichert werden. Also im new_values.txt sind nur die neuen Werte drin, formatiert:

748347832
4723489,38
4786


Und im values.dat ist die allgemeine Struktur, in der die Werte regelmäßig aktualisiert werden, da sind z. B. Temperaturwerte, Feuchtigkeitswerte usw. so angegeben:

$ - next: temp
37626
685
$ - end temp

Und nach dem Durchlauf muß zwischen den Trennwörtern die neuen Werte stehen, also:

$ - next: temp
748347832
4723489,38
4786

$ - end temp


Error 4386 ist einfach ein Error-code, den ich selber behandeln will, um zu wissen an welcher Stelle das Programm abgebrochen wurde.

Den Code werd ich gleich ändern.
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Sonntag 22. März 2009, 10:02

Dein Code wirkt sehr umständlich. Zeile 4 und 9 sind überflüssig. Ein modernes Python vorausgesesetzt, ist `with` besser als das explizite Schließen von Dateien. Benenne die Schleifenvariablen besser. Und benutze überhaupt eine Schleife - das war doch dein Problem, oder? Der zweite Parameter von `index` sagt, wo die Suche beginnt. Statt Zeile 21-26 kann man Slices auch zuweisen. Statt Errorcodes sollte man Exceptions benutzen. Und wenn man sie fängt, immer nur die fangen wollen, die auch geworfen wird. Da du weißt, dass es `readlines` gibt, wundert es mich, dass du `writelines` nicht gefunden hast.

Code: Alles auswählen

with open("values.txt") as f:
    values = f.readlines()

with open("new_values.txt") as f:
    new_values = f.readlines()

stop = 0
while True:
    try:
        start = values.index('...', stop)
        stop = values.index('...', start)
        values[start + 1:stop] = new_values
    except ValueError:
        break

with open("values.txt") as f:
    f.writelines(values)
Stefan
ivka_sto
User
Beiträge: 63
Registriert: Dienstag 11. Dezember 2007, 23:13

Sonntag 22. März 2009, 13:13

Hallo Stefan,

Danke für die Hinweise.
Wie ich rausgefunden habe, ist das Problem nicht in der Schleife, das Problem ist, daß das erste .index() ganz normal gefunden wird, und das zweite ein ValueError zurückgibt, da 'list.index(x): x not in list' Ich schreibe beide gleich, der jeweilige String mit '\n' am Ende, das eine wird gefunden, das zweite nicht :(

Code: Alles auswählen

start = values.index('$ - beg - temp\n')
print str(start)
stop = values.index('$ - end - temp\n')
print str(stop)
Ich habe auch in der Liste selber gesucht, mit Angabe von dem Index, den ich im File ausgelesen habe, und '$ - beg - temp' und '$ - end - temp' habven sogar dieselbe Zeichenanzahl, doch das zweite values.index() gibt ValueError zurück :( Bin ratlos ..
[/code]
BlackJack

Sonntag 22. März 2009, 13:37

@ivka_sto: Das bedeutet dann, dass die zweite Zeichenkette so einfach nicht als Zeile in der Datei vorkommt.
ivka_sto
User
Beiträge: 63
Registriert: Dienstag 11. Dezember 2007, 23:13

Sonntag 22. März 2009, 13:44

Ich hab mir die Elemente der beiden Strings ausgeben lassen mit

Code: Alles auswählen

a = values[3606]
b = values[3607]
for i in a:
   print i, '.'
for i in b:
   print i, '.'
Und als Ergebnis kriege ich für das zweite ein Zeichen mehr:

$. $.
_. _.
b. e.
e. n.
g. d.
_. _.
t. t.
e. e.
m. m.
p. p.
_ .
. _
o .

(_ ist blank, o ist nichts, nur damit der Punkt unter dem zweiten String kommt)

Was kommt denn nach dem letzten sichtbaren Zeichen im zweiten String? Beim ersten ist es \n. wie gewollt, beim zweiten ist es .\n. Was fehlt? Sieht es jemand?
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Sonntag 22. März 2009, 14:24

Mach doch mal

Code: Alles auswählen

print repr(a)
print repr(b)
Das dürfte etwas übersichtlicher sein.
MfG
HWK
ivka_sto
User
Beiträge: 63
Registriert: Dienstag 11. Dezember 2007, 23:13

Sonntag 22. März 2009, 14:49

@ HWK:
Gott segne dich, mein Kind :D


Das erste ist '$ - beg - temp\n', und das zweite '$ - end - temp\r\n'

Ich hätte noch ewig rumprobieren können .. vielen lieben Dank allerseits, daß ihr euch die Zeit genommen habt, meine Fehler zu korrigieren.

Viele Grüße,
ivka_sto
Antworten