Probleme mit append() an Liste

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
Daiwah
User
Beiträge: 8
Registriert: Montag 18. Oktober 2004, 09:43
Wohnort: Berlin

Hallo:
Ich habe eine Funktion, die in einer Schleife Dictionaries an eine Liste anbinden soll. Das jeweilige Dictionary (indexdict) wird von einer anderen Funktion gefüllt, die vorher aufgerufen wird (macht der xml-parser).
Das Anhängen an die Liste sieht so aus:

Code: Alles auswählen

def parseList(self, filelist):
        tmplist=[]
         for filename in filelist:
            #setup xml-parser (must be done every time)
            p= xml.parsers.expat.ParserCreate('ISO-8859-1')
            p.StartElementHandler = self.start_file_element
            print filename
            #start parsing
            try:
                p.ParseFile(open(filename, 'r'))
            except:
                pass #just ignore xml-errors

            print"\nAppend to list:"
            print self.indexdict

            tmplist.append(self.indexdict)
            
            print "Outputlist: "
            print tmplist
        return tmplist
In self.indexdict steht jedesmal der korrekte Wert, nur beim append hapert es.
Am Ende steht in der Liste tmplist der Inhalt des letzten self.indexdict, allerdings 5x hintereinander (Schleife läuft bei mir 5x).
Ich find den Fehler einfach nicht.
fs111
User
Beiträge: 170
Registriert: Samstag 15. November 2003, 11:42
Kontaktdaten:

Wieso sollte da Deiner Meinung nach was anderes stehen? Du hängst doch auch immer wieder self.indexdict an, weißt diesem aber nie einen neuen Wert zu, oder passiert das in einer ganz anderen Methode?

fs111
Pydoc-Integration in vim - Feedback willkommen: http://www.vim.org/scripts/script.php?script_id=910
Daiwah
User
Beiträge: 8
Registriert: Montag 18. Oktober 2004, 09:43
Wohnort: Berlin

Doch, weil der Xml-Parser bei jedem Durchgang eine Datei durchsucht und eine Methode aufruft (start_file_element), die dann self.indexdict füllt.
Das
print"\nAppend to list:"
print self.indexdict
zeigt auch, das der Wert korrekt drinsteht, nur das anhängen klappt halt nicht.
Der Vollständigkeit halber hier noch die Methode start_file_element, die von p.ParseFile() aufgerufen wird:

Code: Alles auswählen

    def start_file_element(self, name, attrs):
   
        #put statistic and info tags in our xml dictionary
        if name=='statistic' or name=='info':
            self.indexdict[name]=attrs
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

mach noch ein self.indexdict = {} vor dem parsen von jedem file

Code: Alles auswählen

    for filename in filelist:
            #setup xml-parser (must be done every time)
            self.indexdict = {}
            p= xml.parsers.expat.ParserCreate('ISO-8859-1')
            p.StartElementHandler = self.start_file_element
            print filename 
so erstellst du für jedes file ein dictionary, sonst fügst du ja jedesmal dasselbe dem array hinzu

gruss
Gast

Jooo, das hats gebracht...
Ich versteh zwar nicht so ganz wieso, weil ich dachte, dass die start_file_element - Methode das Dctionary auch so überschreibt, aber in jedem Fall hat's geklappt...

Vielen Dank !
Daiwah
User
Beiträge: 8
Registriert: Montag 18. Oktober 2004, 09:43
Wohnort: Berlin

Ahdoch, jetzt versteh ich's :D
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Ja es überschreibt es
Mal ein kleines Bsp:

Code: Alles auswählen

a = []
b = {'test':3}
a.append(b)
b['test'] = 4
a.append(b)

print a #-> [b,b] -> [{'test':4},{'test':4}]
Die Elemente im Array sind dieselben wie du gerade veränderst (b)
Also wenn du b veränderst sind die Elemente im Array auch anders weil es ja die genau die selben sind.

Das ganze ist weil alle Variabeln (bis auf wenig immutable types, z.B. zahlen) Pointer auf die Objekte sind.
Also b ist nur ein Zeiger auf das Dictionary, wenn du den Zeiger kopierst, erstellst du nie ein neues sonder veränderst immer dasselbe Dictionary weil im Array auch nur die Zeiger sind die auf immer das gleiche Dictionary zeigen.

Wenn du jetzt b = {} machst erstellt python ein neues Dictionary und b zeigt auf dieses Dictionary und das andere gibts immernoch, ist aber nur noch vom Array aus zu erreichen.

So funktioniert es auch mit den Funktionen:

Code: Alles auswählen

def test(parameter):
    print parameter

test('hallo') #ruft die funktion auf

test2 = test #kopiert nur den Zeiger auf die Funktion, führt die Funktion nicht aus weil keine Klammern angegeben wurden
test2('hallo') #ruft nun die gleiche funktion auf wie test weil ja test und test2 auf die gleiche funktion zeigt
irgendwie ist Zeiger erklären doof so ohne ,ündliche Erklärungen :D

hat einer grad ein schönes Tutorial oder so, wo sie anständig erklärt werden?

Gruss

*edit* grml warum muss ich nur immer grad auf antworten reagieren :)
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Hi rayo,

wenn Du im Forum stöberst, findest Du einige Erklährungen zu OOP, Instanzen, Referenzen ...
z.B. http://python.sandtner.org/viewtopic.php?t=1132


Gruß

Dookie
[code]#!/usr/bin/env python
import this[/code]
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Nicht für mich, aber wenn er es nun begriffen hat, ists ja egal :D

gruss
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Für alle anderen natürlich auch ;)

Dookie
[code]#!/usr/bin/env python
import this[/code]
Daiwah
User
Beiträge: 8
Registriert: Montag 18. Oktober 2004, 09:43
Wohnort: Berlin

Sorry, dass Du Dir jetzt die Mühe der Erklärung gemacht hast während ich hinter Deinem Rücken geschrieben hab :D

Hat es auf jedenfall nochmal verdeutlicht!

Besten Dank!
Antworten