Liste in .txt schreiben

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
Ligurio
User
Beiträge: 22
Registriert: Montag 23. November 2015, 11:00

Huhu ich bins mal wieder mit einem kleinen Problem:
Dieser Code liest Werte Zeilenweise in eine Liste aus einer .txt (diese ist in 2 spalten mit Tabs getrennt)

Code: Alles auswählen

Liste=[]
Liste2=[]
Datei = open("ASCII-Tabelle.txt","r")
for line in Datei:
    line=line.rstrip()      #rstrip() entfernt unnötige leerzeichen und \n
    line=line.split("\t")   #line ist automatisch eine Liste
    Liste.append(line)      #reiht die Listen(line) aneinander = verschachtelt

Element=Liste[1][1]         #Element in der verschachtelten liste [Zeile][Spalte]
spalte=1                    #0 = 1.Spalte // 1 = 2.Spalte in der .txt
zeile=0
Zeile=Liste[zeile]
Element2=Liste[zeile][spalte]
soweit so gut . Ich würde mich freuen wenn mir einer mit meiner Liste die ich "Liste" genannt habe weiterhelfen könnte. hier habe ich nämlich durch die verschachtelung die möglichkeit schnell mal ein bestimmtes Element zu ändern in dem ich es später dann mit zeile:spalte anspreche. Jedoch weiß ich grad echt nicht wie ich diese so "verschachtelte" liste ohne große umstände wieder in eine .txt schreiben kann.
wenn ich "Liste" ausgebe sieht das ganze dann schonmal so aus:
[['Einstellung 1', 'neu'], ['Einstellung 2', '10'], ['Einstellung 3', '15.5']]


schreiben wollte ich gerne so:
Datei = open("ASCII-Tabelle2.txt","a")
Datei.writelines(["%s\n" % item for item in Liste])

aber hier werden mir die Klammern und "stringzeichen" mit in die txt geschrieben.
['Einstellung 1', 'neu']
['Einstellung 2', '10']
['Einstellung 3', '15.5']

mit replace() habe ich schon eine möglichkeit gefunden meine Liste zu bereinigen, ist aber denke ich viel zu umständlich:

Code: Alles auswählen

zeile = 0
for x in range(0,3):
    Zeile=str(Liste[zeile])
    Zeile=Zeile.replace(',','')
    Zeile=Zeile.replace('[','')
    Zeile=Zeile.replace(']','')
    Zeile=Zeile.replace("'",'')
    Datei.write("%s\n" % Zeile)
    zeile+=1
Könnte mir wer weiterhelfen?
Danke schon im vorraus ;)
BlackJack

@Ligurio: Du musst halt statt die Zeichenkettendarstellung von der Liste zu erstellen eine Zeichenkette aus den Elementen in der Liste erstellen. Zum Beispiel in dem Du das ”Gegenteil” von `split()` machst: die `join()`-Methode. Oder per Zeichenkettenformatierung (in neuem Code eher mit `format()` statt mit ``%``) nicht die ganze Liste sondern die beiden Elemente mit jeweils einem eigenen Platzhalter in eine Vorlage formatieren.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@Ligurio: zum Lesen und Schreiben solcher doppelter Listen gibt es schon ein fertiges Modul: csv
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Ligurio hat geschrieben:aber hier werden mir die Klammern und "stringzeichen" mit in die txt geschrieben.
Die Klammern und Anführungszeichen sind Bestandteil der Repräsentation dieser Liste (nicht der Liste selber!) und es ist in der Tat keine gute Idee, das so direkt zum Speichern zu verwenden. Du bekommst ohnehin ein Problem wenn du die Daten wieder einlesen möchtest. Was in der Datei steht ist Text (oder korrekter: eine Ansammlung von Bytes) und kann nicht wieder ohne entsprechendes Parsing in eine Python-Datenstruktur eingelesen werden.

Aus diesem Grund wählt man für das Speichern und Laden üblicherweise geeignete Bibliotheken. In der Standard-Library wären das beispielsweise csv oder json.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Und nebenbei bemerkt: Dateien sollte man immer mittels ``with open(...) as filehandle`` öffnen. Damit wird die Datei auf jeden Fall sauber geschlossen, ohne dass man sich explizit darum kümmern muss.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Ligurio
User
Beiträge: 22
Registriert: Montag 23. November 2015, 11:00

Vielen Dank für die zahlreichen tipps!
habe das Problem nun lösen können.

hier ist mal mein kompletter Code um eine txt zu lesen => in Textfeldern anzeigen zu lassen oder um die geänderten werte wieder richtig in die Datei zu schreiben. (sollte eine art "Einstellungs logfile" für nen raspberry im Auqarium werden :mrgreen: )

Code: Alles auswählen

from PyQt4.QtGui import QApplication
from PyQt4.uic import loadUi
import sys
Einstellung_name=[]                                     #Definition der Listen
Einstellung_werte=[] 
class Window(object):
    def __init__(self):
        self.ui = loadUi('.txt import-export.ui')
        self.ui.Button.clicked.connect(self.Schreiben)
        self.ui.Button2.clicked.connect(self.Lesen)
        self.ui.show()
        #Zur Übersicht
#_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-       
#           Eigentlich muss nur hier geändert werden !!! (solange 2 einstellungen gespeichert sind)
#           Position der Einstellungen in der .txt
        global Wassertemp,Fuellstand                     #Position der Einstellungen in der .txt
        Wassertemp=0                                     #0 = 1.Zeile in der .txt
        Fuellstand=1                                     #1 = 2.Zeile in der .txt
        #CO2 gehalt=2 usw
#_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-   

    def Oeffnen(self):       
        del Einstellung_name[:]                          #leert die Liste (den Inhalt) der 1.Spalte
        del Einstellung_werte[:]                         #leert die Liste (den Inhalt) der 2.Spalte
        Datei = open("ASCII-Tabelle.txt","r")            #r=read
        for line in Datei:                               #für jeder Zeile in der .txt
            line=line.rstrip()                           #rstrip() entfernt unnötige leerzeichen und \n
            line=line.split("\t")                        #fügt alle Werte der Zeile die mit einem "Tab (\t)" getrennt sind in eine Liste
            Einstellung_name.append(line[0])             #reiht nur die Werte der 1. Spalte aneinander == [0]   
            Einstellung_werte.append(line[1])            #reiht nur die Werte der 2. Spalte aneinander == [1]
        Datei.close()   
        
    def Lesen(self):
        self.Oeffnen()                                   #Funktion "Oeffnen" starten
        print Einstellung_name                           #zur Kontrolle ausgegeben
        print Einstellung_werte
        self.ui.Optionsfeld1.setText(Einstellung_name[Wassertemp])    #Schreibt die jeweiligen Werte in das Textfeld
        self.ui.Optionsfeld2.setText(Einstellung_name[Fuellstand])
        self.ui.Optionsfeld3.setText(Einstellung_werte[Wassertemp])
        self.ui.Optionsfeld4.setText(Einstellung_werte[Fuellstand])
#_-_-_-_hier analoge Ergänzung weiterer Einstellungen-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-  
        
    def Schreiben(self):
        self.Oeffnen()                                   #Funktion "Oeffnen" muss durchgefürt werden, um die Liste mit den Werten zu füllen
        #Überprüfung ob ein Feld leer => sonst wird die .txt leer überschrieben
#_-_-_-_hier analoge Ergänzung weiterer Optinsfelder die nicht "leer" sein dürfen-_-_-_-_-_-_-_-_-_-_-
        if self.ui.Optionsfeld1.text() == "" or self.ui.Optionsfeld2.text() == "" or self.ui.Optionsfeld3.text() == "" or self.ui.Optionsfeld4.text() == "" :
            self.ui.Status.setText("Fehler!!! ein Optionsfeld leer")
        else:
            Datei = open("ASCII-Tabelle.txt","w")   #nachdem die Liste voll ist, wird die Datei neu geöffnet mit schreibrechten
            Einstellung_name[Wassertemp]=self.ui.Optionsfeld1.text()  #übergibt den Inhalt des Textfeldes an die entsprechende stelle in der Liste
            Einstellung_name[Fuellstand]=self.ui.Optionsfeld2.text()
            Einstellung_werte[Wassertemp]=self.ui.Optionsfeld3.text()
            Einstellung_werte[Fuellstand]=self.ui.Optionsfeld4.text()
#_-_-_-_-_-_hier analoge Ergänzung weiterer Einstellungen-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-  

            for x in range(0,len(Einstellung_name)):                             #len(Liste) anzahl der Elemente in der Liste == entspricht der gesamten Zeilenanzahl == start bei x=0 (1.Zeile)
                Zeile_komplett = Einstellung_name[x]+"\t"+Einstellung_werte[x]     #schreibt die jeweiligen Werte der Liste mit einem \t getrennt in die Zeilenvariable (Zeile_komplett)   
                Datei.writelines("%s\n" % Zeile_komplett)                    #schreibt Wert in Zeile
                x+=1
            Datei.close()
            self.ui.Status.setText("Einstellungen in die .txt gespeichert")
                
def main():
    app = QApplication(sys.argv)
    window = Window()
    app.exec_()     
              
if __name__ == '__main__':
    main()
Antworten