Mehrere .txt Datein in ein Array einfügen

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
Neuling7
User
Beiträge: 3
Registriert: Mittwoch 26. Juli 2017, 15:54

Hi liebe Freunde,
das ist mein erster Post ich hoffe jemand kann mir helfen :S
Es geht darum, ich mache bzw. versuche gerade für eine Hausarbeit ein Programm in Python zu schreiben.

Code: Alles auswählen

def getValues(filename):
    try:
        file = open(filename, "r")  
    except IOError:
        print ("Problem mit der Datei")

    values = []
    for line in file:
        values.append(line)
    return values


i=1
while i <= 4:
    i += 1
    textstring4 = []
    textstring3 = getValues(eingabe+str(i)+".txt")
    textstring4 = textstring4 + textstring3
Es sollen also die Werte, die aus den Textdateien während der whileschleife in textstring3 gespeichert werden zu textstring4 addiert werden.
Leider habe ich jetzt das Problem, dass nur die letzten Werten in das Array hinzugefügt werden und die vorigen immer gelöscht werden. Ich denke mal die Lösung ist sehr einfach aber ich komme einfach nicht drauf :(

Ich danke euch schon mal !!
Zuletzt geändert von Anonymous am Mittwoch 26. Juli 2017, 16:08, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@Neuling7: zur Namensgebung: getValues sollte read_values heißen oder noch besser, aussagen, welche Art von Values da gelesen wird. Was sollten die Nummern an textstring4 oder textstring3?

Deine Fehlerbehandlung in getValues ist keine und kann gleich gelöscht werden, denn im Fehlerfall ist "file" nicht definiert und löst zwei Zeilen später die nächste Exception aus. Welche Probleme mit der Datei existieren, sagt die Meldung auch nicht. Dateien sollten auch wieder geschlossen werden.

Deine while-Schleife ist eigentlich eine for-Schleife, und Du setzt in jedem Schleifendurchgang textstring4 wieder auf eine leere Liste. Was erwartest Du also?

Statt aus zwei Listen eine neue zu erstellen, kannst Du die erste Liste einfach um die zweite erweitern.

Code: Alles auswählen

def read_values(filename):
    with open(filename) as lines:
        return list(lines)

all_lines = []
for i in range(1,5):
    all_lines.extend(read_values("{}{}.txt".format(eingabe, i))
Neuling7
User
Beiträge: 3
Registriert: Mittwoch 26. Juli 2017, 15:54

@Sirius3

Mega 1000 dank werde es sofort probieren.

BIn leider ein Programmierneuling deshalb die anscheinend dumme Fehler. Die Nummern bei Textring3 und 4 stehen, weil ich sowohl textstring1 und 2 schon vorher definiert hatte.
BlackJack

@Neuling7: Bitte sofort aufhören irgendwelche Nummern an Namen anzuhängen sondern gleich sinnvolle Namen wählen. Die sind nicht nur für den Leser wichtig um ein Programm zu verstehen, sondern auch wenn der Autor eines Programms schwierigkeiten hat einen sinnvollen Namen für etwas zu finden, ist das sehr oft ein Zeichen dafür das es ein Problem gibt. Zum Beispiel weil der Autor selbst nicht wirklich verstanden hat was für einem Wert er da einen Namen gibt, oder weil der Wert aus mehreren nicht wirklich zusammengehörenden Werten zusammengesetzt ist.

`textstring` ist an sich schon kein guter Name für einen Wert der gar keine Zeichenkette mit Text ist. Das ist eine Liste und Listen (und anderen Sequenzen) gibt man in der Regel die Mehrzahl von dem Namen der für ein einzelnes Element passend wäre. Die einzelnen Elemente sind Zeilen aus Dateien, also währe `lines` ein guter Name. Zumindest solange man nicht mehr über die Bedeutung dieser Zeilen weiss.

Du kennst doch bereits ``for``-Schleifen, warum dann die ``while``-Schleife? ``while``-Schleifen verwendet man wenn man keinen einfachen Weg hat ein iterierbares Objekt über Werte zu erstellen. Ein `range()`-Objekt ist aber leicht erstellt, spart zwei Zeilen Code ein, und macht das ganze einfacher, denn man kann am Schleifenkopf alles ablesen und muss nicht den ganzen Schleifenkörper nach potentiellen Veränderungen von `i` absuchen.

`eingabe` ist nirgends definiert und führt zu einem `NameError`.

Das zusammenstückeln von literalen Zeichenketten und Werten mit ``+`` und `str()` ist eher BASIC als Python. In Python gibt es dafür Zeichenkettenformatierung mittels `format()`-Methode.

`getValues()` sollte `get_values()` heissen. Mehr zu konventionellen Namensschreibweisen findet sich im Style Guide for Python Code.

Die Ausnahmebehandlung ist so nicht sinnvoll, denn wenn die Datei nicht geöffnet werden konnte, dann ist auch der Name `file` nicht definiert — beziehungsweise haben wir hier gleich ein weiteres Problem: `file` ist bereits definiert, und zwar ist das der Name für Python's Dateityp. Und das führt dann ein paar Zeilen weiter zu dem nächsten Problem das man über den Dateityp nicht iterieren kann:

Code: Alles auswählen

In [17]: for line in file:
    ...:     pass
    ...: 
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-17-23873b411703> in <module>()
----> 1 for line in file:
      2     pass

TypeError: 'type' object is not iterable
Eine *sinnvolle* Fehlerbehandlung ist ganz selten nur ein `print()` und dann so weitermachen als sei gar kein Fehler aufgetreten, denn der nachfolgend ausgeführte Code geht ja davon aus es sei keine Ausnahme aufgetreten und macht weiter als sei alles in Ordnung. Du musst Dir hier also überlegen was die Funktion machen/zurückgeben soll/muss wenn die Datei nicht geöffnet werden konnte. Beziehungsweise ob diese Ausnahme *in* der Funktion überhaupt sinnvoll behandelt werden kann, oder ob das nicht eher eine Entscheidung ist, die man dem Aufrufer überlassen muss/sollte.

Die Werte in die `values`-Liste zu bringen ist komplizierter gelöst als nötig denn man kann `list()` einfach ein iterierbares Objekt übergeben und bekommt dann eine Liste mit den Elementen zurück.

Du öffnest die Dateien, schliesst sie aber nicht wieder. Das sollte man aber tun. Am besten schaust Du Dir in dem Zusammenhang mal die ``with``-Anweisung an.

Das Problem mit dem Code ist das da keine vorherigen Werte aus der Liste (ein Array ist etwas anderes!) gelöscht werden, sondern das Du in jedem Schleifendurchlauf mit einer *neuen* Liste anfängst. Du willst *vor* der Schleife die Liste anlegen. In `getValues()` hast Du es doch auch so gemacht.

Zudem ist die ``+``-Operationen auch ineffizient denn damit erstellst Du jedes mal eine neue Liste in die alle Elemente der beiden Operanden kopiert werden und die alte Liste `textstring4` wird danach gelöscht beziehungsweise zum Löschen freigegeben. Es wäre sinnvoller die Liste einfach um die neuen Werte zu erweitern.

Ungetestet:

Code: Alles auswählen

def main():
    eingabe = 'test'
    lines = list()
    for filename in ('{}{}.txt'.format(eingabe, i) for i in range(1, 5)):
        try:
            with open(filename) as file_lines:
                lines.extend(file_lines)
        except OSError:
            print('Probleme bei Datei {0!r}.'.format(filename))

    print(lines)
                


if __name__ == '__main__':
    main()
Neuling7
User
Beiträge: 3
Registriert: Mittwoch 26. Juli 2017, 15:54

@BlackJack

WOW echt vielen Dank für die ganzen Tipps werde die mir auf jeden Fall zu Herzen nehmen und werde mir auch die Anweisungen mal angucken.
Danke außerdem, dass du dir die Zeit genommen hast mir so ausführlich zu Antworten.
Bis jetzt habe ich nicht so viel mit der for Schleife gemacht weil ich die noch nicht so ganz verstanden hatte aber werde mich mal mit der auseinandersetzen.
Das war nur ein kleiner Teil von dem Code den ich schon geschrieben hatte wollte den aber natürlich nicht ganz hier kopieren weil der ziemlich lang ist und da ist dann "eingabe" schon definiert.

Naja nochmal vielen Dank :D :D
Antworten