aus txt auslesen

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.
lukasmarti
User
Beiträge: 31
Registriert: Samstag 8. April 2006, 17:10
Wohnort: lachen (schweiz)

Hallo

Wie kann man aus eine txt Datei zeilen auslesen und den text der zeilen dann eine Variableb zuordnen?
z.B. for a in ("test.txt erste zeile") range(19):

und das mit allen zeile.
Das am Schluss der Inhalt der ersten Zeile der Variablen zeile1 zugeordnet ist , und der der zweiten zeile der Variablen zeile2 u.s.w

Danke
Bernhard
User
Beiträge: 136
Registriert: Sonntag 15. Januar 2006, 20:31
Wohnort: Greifswald
Kontaktdaten:

Die Funktion, die Du suchst heißt readlines(). Du brauchst ein file-Objekt das Du mit file() oder open() erstellst und kannst dann mit for über readlines() iterieren. Die Hilfe-Funktion (in IDLE mit F1) oder google helfen Dir weiter.

Du erhälst dann keine Variablen zeile1 und zeile2 sondern eine Werteliste, in der die Zeilen enthalten sind. Wenn das Wort "Liste" bei Dir kein "Aha" auslöst, brauchst Du nicht "readlines()" sondern einen guten Einführungstext in Python.

Gruß,
Bernhard
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

lukasmarti hat geschrieben:Das am Schluss der Inhalt der ersten Zeile der Variablen zeile1 zugeordnet ist , und der der zweiten zeile der Variablen zeile2 u.s.w
Hallo lukasmarti!

Am Einfachsten ist es, wenn du den kompletten Text in eine Liste einliest. Dann hast du eine Variable, mit dem kompletten Text und du kannst trotzdem auf jede einzelne Zeile zugreifen.

Code: Alles auswählen

f = file("textdatei.txt", "r")
testliste = f.readlines()
f.close()
print textliste
Hier habe ich noch einen, hoffentlich interessanten, Link für dich: http://www.python-forum.de/topic-6157.html

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
lukasmarti
User
Beiträge: 31
Registriert: Samstag 8. April 2006, 17:10
Wohnort: lachen (schweiz)

Danke für die Antworten.

Aber was muss ich jetzt machen, wenn ich immer drei zeilen in eine eigene txt schreiben will?
Bernhard
User
Beiträge: 136
Registriert: Sonntag 15. Januar 2006, 20:31
Wohnort: Greifswald
Kontaktdaten:

Die eigene txt aufmachen, jeweils drei Zeilen reinschreiben (die Funktion/Methode heißt write() (wie man in Gerolds Link nachlesen kann), dann mit close() schließen und die nächste txt aufmachen.
Schreib einfach, was davon Dein Problem ist, und was Du selbst kannst.
lukasmarti
User
Beiträge: 31
Registriert: Samstag 8. April 2006, 17:10
Wohnort: lachen (schweiz)

Code: Alles auswählen

zeile = f.readlines()
for a in range(99):
    datei = open("login"+a".txt", "w")
    datei.write("""die erste zeile ist die zeile"""+zeile[0]+
"""und das ist die zeile"""+zeile[1]+
"""und das ist zeile """+zeile[2]+""")
wenn ich das so mache kommt die fehlermeldung
integer und string nicht kompinieren kann.

Die Schleife soll sich solange wiederholen bin die txt fertig ist und bei jedem durchgang die nächsten 3 zeilen in die txt schreiben.

Danke
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Du willst also nur die erste 3 Zeilen von der Datei einlesen und die dann in verschiedene Dateien schreiben?

Das geht so:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from itertools import izip
import sys
import os


path = os.path.join(sys.path[0], 'foobarblubb.txt')
f = file(path, 'rb')
file_content = list()

# Es sollen ja nur die ersten 3 Zeilen eingelesen werden, also müssen wir nicht
# die ganze Datei einlesen, was Speicherverschwendung wäre. 
for line, dummy in izip(f, xrange(3)):
    file_content.append(line)
f.close()

print file_content

# In die Dateien schreiben.
for post_fix in xrange(10):
    p2f = os.path.join(sys.path[0], 'login%d.txt' % post_fix)
    f = file(p2f, "w")
    f.write(
        "die erste zeile ist die zeile %s"
        "und das ist die zeile %s"
        "und das ist zeile %s" %(
            file_content[0], file_content[1], file_content[2]
        )
    )
    f.close()
lg
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Bernhard hat geschrieben:[...]
und kannst dann mit for über readlines() iterieren.
Man kann auch direkt über das ``file``-Objekt iterieren.

Code: Alles auswählen

f = file(path, 'rb')
for line in f:
    print line,
f.close()
Bernhard
User
Beiträge: 136
Registriert: Sonntag 15. Januar 2006, 20:31
Wohnort: Greifswald
Kontaktdaten:

Hallo!

Deine Fehlermeldung kam daher, dass Du in Deinem Ausdruck

Code: Alles auswählen

"login"+a".txt"
versucht hast, einen String ("login") und eine Zahl (a) mit plus zu verknüpfen. Du musst in so einem Fall die Zahl (a) vorher in einen String umwandeln ( str(a) ). Der Ausdruck

Code: Alles auswählen

"login"+str(a)+".txt"
würde funktionieren. Eleganter ist natürlich das von sape benutzte

Code: Alles auswählen

'login%d.txt' % post_fix
welches die gleiche Aufgabe übernimmt.

Gruß,
Bernhard
Benutzeravatar
sunmountain
User
Beiträge: 89
Registriert: Montag 13. März 2006, 17:18

Ich finde diese Schreibweise beim Schreiben in Dateideskriptoren
einfacher (mein Geschmack), und es spart das explizite newline:

Code: Alles auswählen

f_out = open("test_out.txt",'w')
print >>f_out,"1. Zeile"
print >>f_out,"2. Zeile"
print >>f_out,"3. Zeile"
f_out.close()
Vor allem kann man damit (z.B. für's Debugging) sowas machen:

Code: Alles auswählen

import sys
debug=True
if debug:
    f = sys.stdout
else:
    f = open('outfile.txt','w')

# ne Menge Code ...

print >>f,"Eine Zeile"
So wird je nach Inhalt der Variablen "debug" entweder auf stdout
oder in die Datei geschrieben.
Sehr praktisch, wie ich finde.
BlackJack

sunmountain hat geschrieben:Ich finde diese Schreibweise beim Schreiben in Dateideskriptoren
einfacher (mein Geschmack), und es spart das explizite newline:
Hey `explicit is better than implicit`. :-)
Vor allem kann man damit (z.B. für's Debugging) sowas machen:

Code: Alles auswählen

import sys
debug=True
if debug:
    f = sys.stdout
else:
    f = open('outfile.txt','w')

# ne Menge Code ...

print >>f,"Eine Zeile"
So wird je nach Inhalt der Variablen "debug" entweder auf stdout
oder in die Datei geschrieben.
Sehr praktisch, wie ich finde.
Das hat doch aber überhaupt nichts mit ``print`` oder `write` zu tun!? Ob Deine letzte Zeile nun ``print >>f, "blah"`` oder ``f.write('blah\n')`` heisst, ist ziemlich egal.

Ausserdem sind schon Newlines an den Zeilenenden wenn die Datei mit `readlines()` eingelesen wurden, bei der ``print``-Variante hätte man dann immer eine Leerzeile nach jeder Zeile die man ausgibt.
lukasmarti
User
Beiträge: 31
Registriert: Samstag 8. April 2006, 17:10
Wohnort: lachen (schweiz)

sape hat geschrieben:Du willst also nur die erste 3 Zeilen von der Datei einlesen und die dann in verschiedene Dateien schreiben?
fast

Ich will eine for Schleife machen die den text aus einer txt ausliest und denn im ersten Durchgang die erten drei zeilen in eine txt schreiben und in zweiten Durchgang die zeile 4-6 in eine andere txt schreiben u.s.w.

Also dei txt in kleine txts von je 3 zeile Inhalt teilen.
lhorn
User
Beiträge: 8
Registriert: Freitag 25. Februar 2005, 09:45

lukasmarti hat geschrieben:Ich will eine for Schleife machen die den text aus einer txt ausliest und denn im ersten Durchgang die erten drei zeilen in eine txt schreiben und in zweiten Durchgang die zeile 4-6 in eine andere txt schreiben u.s.w.
Wie wäre es hiermit:

Code: Alles auswählen

#!/usr/bin/env python

linecounter = 0
outcounter = 0
out = None

for line in open("in.txt"):
    if linecounter % 3 == 0:
        try:
            out.close()
        except:
            pass
        out = open("out%d.txt" % outcounter, "w")
        outcounter += 1
    out.write(line)
    linecounter += 1

try:
    out.close
except:
    pass
[/code]
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

lukasmarti hat geschrieben:
sape hat geschrieben:Du willst also nur die erste 3 Zeilen von der Datei einlesen und die dann in verschiedene Dateien schreiben?
fast

Ich will eine for Schleife machen die den text aus einer txt ausliest und denn im ersten Durchgang die erten drei zeilen in eine txt schreiben und in zweiten Durchgang die zeile 4-6 in eine andere txt schreiben u.s.w.

Also dei txt in kleine txts von je 3 zeile Inhalt teilen.
So könntest du das machen. Ich hab das ganze ein wenig flexibler gemacht. Bei ``.get_lines_combined()`` kannst du angeben, wie viele Zeilen zusammengefast werden sollen. So, kannst du z.B. eine 4 angeben und es werden immer 4 Zeilen auf verschiedene Dateien aufgeteilt.

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 


from itertools import izip, count
import sys
import os


class FileContent(object):
    def __init__(self, filename):
        self.filename = filename
                
        f = file(path, 'rb')
        self.file_content = f.readlines()
        f.close()
        
    def get_lines_combined(self, order=3):
        tmp = list()        
        for line, idx in izip(self.file_content, count(1)):
            if idx % order == 0:
                tmp.append(line)
                yield tmp
                tmp = list()
            else:
                tmp.append(line)
        if len(tmp) > 0:
            yield tmp
        
        
if __name__ == '__main__':
    path = os.path.join(sys.path[0], 'foobarblubb.txt')
    
    for post_fix, combined_lines in enumerate(FileContent(path).
                                              get_lines_combined(3)):
        p2f = os.path.join(sys.path[0], 'login%d.txt' % post_fix)
        f = file(p2f, "w") 
        f.writelines(combined_lines)
        f.close()
Der Inhalt der Datei, den ich verwendet habe (foobarblubb.txt):

Code: Alles auswählen

foo
bar
blub
spam
eggs
foobarblubb
test2
Bei ``order=3`` von ``get_lines_combined`` wird folgendes erzeugt:

login0.txt:

Code: Alles auswählen

foo
bar
blub
login1.txt:

Code: Alles auswählen

spam
eggs
foobarblubb
login2.txt:

Code: Alles auswählen

test2

Bei ``order=4`` von ``get_lines_combined`` wird folgendes erzeugt:

login0.txt:

Code: Alles auswählen

foo
bar
blub
spam
login1.txt:

Code: Alles auswählen

eggs
foobarblubb
test2
u.s.w.

lg
sape
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Hi!

Ich finde es irgendwie schön, dass man als Programmierer einem Python-Programm immer irgendwie eine persönliche Note geben kann. :mrgreen:

http://paste.pocoo.org/show/781/
http://paste.pocoo.org/show/782/

Das ist wie das Zeichnen eines Bildes. Wenn mehrere Künstler eine Landschaft zeichnen sollen -- auch wenn jeder Künstler die gleiche Landschaft vor Augen hat -- jedes Bild wird anders aussehen. Jeder findet seinen eigenen Weg zum fertigen Bild. Das ist viel mehr als einfach nur vorgegebene Algorithmen in den Computer einzugeben...
Es kommt auch auf die Tageslaune an, wie ein Programm geschrieben wird. Mal ist es einem egal, und man fängt einfach jeden Fehler ab, dann ist man in der Laune, Fehler vor dem Entstehen abzublocken. Mal möchte man etwas spartanisch, nur mit den eigenen Mitteln, machen, dann besinnt man sich wieder auf Module, die man einbinden könnte, usw.

...das Wort zum Donnerstag. ;-)

lg
Gerold
:-)
Zuletzt geändert von gerold am Donnerstag 25. Januar 2007, 20:54, insgesamt 1-mal geändert.
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Unser philosophischer Gerold :D

Deine Analogie mit einem Bild malen ist schön :) Ich vergleiche es auch immer gerne mit dem komponieren eines Stückes.

lg
lhorn
User
Beiträge: 8
Registriert: Freitag 25. Februar 2005, 09:45

Hier noch ein funktionaler Ansatz. Bis auf die Benennung der Ausgabedateien funktioniert es. Lisp wäre hier natürlich lesbarer :wink:

Code: Alles auswählen

#!/usr/bin/env python

step = 3

lines = open("in.txt").readlines()

map(lambda p: open("out%s.txt" % p[0].strip(), "w").writelines(p),
    [lines[s:e] for s, e in
     zip(range(0, len(lines), step),
         range(step, len(lines) + step, step))])
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

lhorn hat geschrieben:

Code: Alles auswählen

#!/usr/bin/env python

step = 3

lines = open("in.txt").readlines()

map(lambda p: open("out%s.txt" % p[0].strip(), "w").writelines(p),
    [lines[s:e] for s, e in
     zip(range(0, len(lines), step),
         range(step, len(lines) + step, step))])
Hi lhorn!

Nett, wirklich nett. :twisted: Ich hatte allerdings ein paar Schwierigkeiten das Programm zu analysieren.

Was so ein paar Zeilenumbrüche und Einrückungen ausmachen:

Code: Alles auswählen

#!/usr/bin/env python

step = 3

lines = open("in.txt").readlines()

map(
    lambda p: open("out%s.txt" % p[0].strip(), "w").writelines(p),
    [
        lines[s:e] for s, e in zip(
            range(0, len(lines), step),
            range(step, len(lines) + step, step)
        )
    ]
)
...so war es ziemlich schnell durchschaubar.

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

FL ist schön, aber dein Ansatz ist ein wenig inkonsistent. Die Streams werden nicht wehrende der Laufzeit des Processes geschlossen (Wenn sie nicht mehr benötigt werden) sondern erst wen er terminiert ist. Da ist bei einem Konsolenprogramm, das sich selbständig beendet, ok. Was machst du aber bei einem Konsollenprogramm/GUI-Programm das solange läuft bis es vom Benutzer beendet wird? Wohl möglich führt der Benutzer diese Funktion öfter aus? Und spätestens dann hast du ein Problem.

Ansonsten angenehm zu Lesen uns schön kurz :)

lg
lhorn
User
Beiträge: 8
Registriert: Freitag 25. Februar 2005, 09:45

An die Streams habe ich auch gedacht. Ich verwende diese Art von Programm fast ausschließlich von der Konsole aus. Benutzerinteraktion findet keine statt und ich weiß auch vorher, wie groß Ein- und Ausgabe sein werden. Ich habe die Umgebung also unter Kontrolle.

Das Arbeiten mit Ein- und Ausgabe ist ja in der funkionalen Programmierung ohnehin nicht so prickelnd. Man handelt sich dabei halt leider immer Nebewirkungen ein, die sich nicht allein als Funktion der Eingabe ergeben.

Ganz funktional ist mein Versuch ja sowieso nicht. Eigentlich müsste ich die Zeilen der einzulesenden Datei inline in den beiden range-Aufrufen und beim Slice-Operator funktional ermitteln. Aber dreimal die selbe Datei einzulesen erschien mir als übertrieben :wink:
Antworten