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.
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:
lhorn
User
Beiträge: 8
Registriert: Freitag 25. Februar 2005, 09:45

gerold hat geschrieben:Was so ein paar Zeilenumbrüche und Einrückungen ausmachen
In der Tat, meine Fassung ist etwas arg kondensiert. Das liegt aber daran, dass ich sie von den inneren Funktionen her geschrieben und erst nachträglich Zeilenumbrüche eingefügt habe. Emacs denkt dabei eher an ein Lisp-artiges Layout. Seid froh, dass ich nicht meine erste funktionierende Version, die im Kern nur aus einer Zeile bestand, gepostet habe :)
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Ja, dann ist alles i.O. Bisher die kürzeste Variante (Wenn man es genau nimmt ist es ja ein Dreizeiler.).

@Gerold:
Dein zweites paste gefällt mir besser als dein erstes, weil du da über ``itertools.count`` iterierst anstatt ``while`` zu nutzen.

lg
lukasmarti
User
Beiträge: 31
Registriert: Samstag 8. April 2006, 17:10
Wohnort: lachen (schweiz)

Zuerst mal: Danke für die vielen Antworten :D

Code: Alles auswählen

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("""das ist linie 1: "+line1
                  """das ist linie 2: "+line2
                  """das ist linie 3: "+line3""")
    linecounter += 1 

try: 
    out.close 
except: 
    pass 


Aber wie muss ich das noch ändern, damit es in die txt noch etwas dazuschreibt?
also:

1.txt
[Das ist linie1: (linie 1 von txt)
das ist linie2: (linie 2 von txt)
das ist linie3: (linie 3 von txt)]

2.txt
[das ist linie1: (linie 4 von txt)
das ist linie2: (linie 5 von txt)
das ist linie3: (linie 6 von txt)]
u.s.w.
das linie1, linie2 und linie3 muss sich aber nicht ändern.

Sorry das ich noch so viele Nachfragen stellen muss, aber dies überschreitet meine Fähigkeiten in Python.
Bernhard
User
Beiträge: 136
Registriert: Sonntag 15. Januar 2006, 20:31
Wohnort: Greifswald
Kontaktdaten:

Sorry, das ich nachfragen muss: Aber was genau willst Du jetzt noch dazu schreiben? Die eckigen Klammern?
Ist jetzt nicht böse, ich verstehe es wirklich nicht.

Bernhard

Edit: Willst Du eine Zeile einfügen, in der die Nummer des txt-Files steht? Also Dein "1. txt", "2. txt", ... ? Diese Information steckt in der Variable outcounter, die jeweils in Zeile 12 hochgezählt wird.

Den Inhalt ausgeben kannst Du, indem Du die Ausgabe in den Zeilen 13 bis 15 anpasst. Zum Beispiel so:

Code: Alles auswählen

        out.write( str(outcounter+1) + ". txt\ndas ist linie 1: "+line1+
                                            "\ndas ist linie 2: "+line2+
                                            "\ndas ist linie 3: "+line3 )
War es das, was Du meintest?
BlackJack

Ich möchte gerne anmerken, dass man `line` nicht mit `linie` sondern `Zeile` übersetzt. Sieht ja schrecklich aus… :-)
lukasmarti
User
Beiträge: 31
Registriert: Samstag 8. April 2006, 17:10
Wohnort: lachen (schweiz)

Wenn das die txt ist:

Code: Alles auswählen

hallo
wie 
geht
es 
dir
heute 
sollen die txt am schluss so aussehen:

1.txt

Code: Alles auswählen

das ist zeile 1:hallo
das ist zeile 2: wie 
das ist zeile 3: geht
2.txt

Code: Alles auswählen

das ist zeile 1: es 
das ist zeile 2: die
das ist zeile 3: heute
Bei euren Forschlag werden die 3 Zeilen ja in der Variablen "line" gespeichert oder ?

ich muss aber die drei zeilen in verschiedene teile der txt hineinschreiben.

die stadart txt muss so aussehen:

Code: Alles auswählen

das ist zeile 1: 
das ist zeile 2: 
das ist zeile 3:
und dann jeweils immer am Ende der zeile in den neuen txts die nächste zeile der ausgangs txt zu schreiben.

Edit (Leonidas): Code-Highlighting abgeschaltet. Wow, das erste mal.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Ich hätte das anzubieten:

Code: Alles auswählen

#!/usr/bin/env python
#! -*- coding: UTF-8 -*-
from __future__ import with_statement
from contextlib import closing

def main():
    template = file('template.txt', 'r')
    templatelines = [line.strip() for line in template.readlines()]
    template.close()

    filecounter = 1
    with closing(file('input.txt', 'r')) as f_in:
        for number, line in enumerate(f_in):
            f_out = file('%s.txt' % filecounter, 'a')
            template_current = number % len(templatelines)
            f_out.write(templatelines[template_current])
            f_out.write(line)
            f_out.close()

            if template_current == len(templatelines) - 1:
                filecounter += 1

if __name__ == '__main__':
    main()
(Achtung, das produziert relativ viel IO, weil es die Datei immer für eine Zeile öffnet, ist aber vergleichsweise flexibel, weil es mit beliebig langen Input und beliebig langen Templates zurecht kommt. Tuning bleibt dem Leser überlassen)
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Bernhard
User
Beiträge: 136
Registriert: Sonntag 15. Januar 2006, 20:31
Wohnort: Greifswald
Kontaktdaten:

@lukasmarti:
Die Textzeilen stecken nicht in einer Variablen line, sondern in den drei Variablen line1, line2 und line3. Was ich glaube, was Du gerne möchtest, das tut das Script jetzt schon. Die Texte in den Anführungszeichen ("das ist linie 1", etc.) werden vor den jeweiligen Textzeilen ausgegeben!?

(Leonidas' Lösung macht das über ein eigenes File template.txt, in dem er die Zusätze getrennt von der Programmlogik unterbringt.)

Gruß,
Bernhard
Antworten