2017-03-22 10 views
1

Ich habe ein Python-Programm, das eine Liste an eine globale Variable anhängen soll, aber statt anzuhängen überschreibt es die Liste. Dies ist eine Demo-Funktion, die ich gemacht, die auf die gleiche Weise funktioniert:Append überschreibt vorhandene Daten in der Liste

var_gobal = [] 

def parse(list_parse,stack): 
    for element in list_parse: 
     stack.append(element["a"]) 
     print(stack) 
     global var_gobal 
     var_gobal.append(stack) 

to_parse = [{"a":"abc","b":"bcd","c":"cde"},{"a":"def","b":"efg","c":"ghi"}] 
parse(to_parse,[]) 
print (var_gobal) 

Die erwartete Ausgabe

[['abc'], ['abc', 'def']] 

sein sollte, aber ich bekomme stattdessen

[['abc', 'def'], ['abc', 'def']] 

Das erste Element der Liste ist überschrieben Warum passiert dies?

+0

Sollte nicht 'global var_global' außerhalb der Schleife sein? – Petar

+0

Gleicher Ausgang macht keinen Unterschied. –

Antwort

2

können Sie slice stack = stack[:] + [element["a"]] statt append Methode der Liste verwenden:

var_gobal = [] 

def parse(list_parse,stack): 
    global var_gobal 

    for element in list_parse: 
     stack = stack[:] + [element["a"]] 
     print(stack) 
     var_gobal.append(stack) 

to_parse = [{"a":"abc","b":"bcd","c":"cde"},{"a":"def","b":"efg","c":"ghi"}] 
parse(to_parse,[]) 
print (var_gobal) 

Ausgang:

['abc'] 
['abc', 'def'] 
[['abc'], ['abc', 'def']] 

Oder stack = stack + [element["a"]] mit demselben Ergebnis führen würde auch.

den Unterschied zu sehen, können wir folgendes Beispiel sehen:

my_list = ['a', 'b'] 
tmp = [] 
global_var = [] 

for i in my_list: 
    tmp.append(i) 
    global_var.append(tmp) 

global_var 

Diese gibt global_var als [['a', 'b'], ['a', 'b']].

Zwar ist tmp zu global_var in jeder Iteration durch my_list angehängt, auf jedem append aller Referenzierung (oder alle, die weisen) zu tmp geändert wird. Stattdessen, wenn slice oder + verwendet wird, neue Liste wird seit [:] mit allen Elementen in der ersten erstellt wird verwendet:

my_list = ['a', 'b'] 
tmp = [] 
global_var = [] 

for i in my_list: 
    tmp = tmp[:] + [i] 
    global_var.append(tmp) 

global_var 

Diese Ergebnisse: [['a'], ['a', 'b']]

+0

Das funktioniert, aber warum verursacht 'stack.append()' ein Problem? –

+1

Ähnlich wie im obigen Fall, wird stack anfänglich mit '['abc']' angehängt und an 'global_var' angehängt. Aber in der nächsten Iteration wird derselbe Stapel mit 'def 'angehängt und wird zu' ['abc', 'def']'. Wenn wir diesen aktualisierten "Stack" anhängen, werden alle Orte von "Stack" verwendet, haben denselben aktualisierten Wert (Arrays werden als Referenz übergeben, hier ist Stack nur ein Array oder eine Liste), so dass sogar bereits angehängte "Stacks" geändert werden . – 0p3n5ourcE

+1

ah ok jetzt verstehe ich. Vielen Dank. –

2

Sie haben Stapel zum VAR_GLOBAL statt Anhängen einer Referenz zu kopieren.

var_gobal.append(stack.copy()) 
+0

Dies gibt einen Fehler 'AttributError: 'Liste' Objekt hat kein Attribut 'Kopie'' –

+0

@PrateekGupta #Patrik Sie haben Recht, aber Sie müssen schreiben' var_gobal.append (kopieren (stack)) ' – stovfl

+0

@PrateekGupta' Liste. copy() 'ist verfügbar von python3.3 –

2

stack will have 2 element after second, that was saved in stack list.

var_gobal = [] 

def parse(list_parse,stack): 
    for element in list_parse: 
     stack.append(element["a"]) 
     print(stack) 
     new_stack = list(stack) 
     var_gobal.append(new_stack) 


to_parse = [{"a":"abc","b":"bcd","c":"cde"},{"a":"def","b":"efg","c":"ghi"}] 
parse(to_parse,[]) 
print (var_gobal) 

>>> print (var_gobal) 
[['abc'], ['abc', 'def']] 
+0

dies funktioniert auch zusammen mit @ Open-Source-Antwort, aber warum muss ich eine andere Liste erstellen? Stack-Variable ist bereits eine Liste, zuerst mit 1 Element, dann nach Schleifen mit 2 Elementen und ich bin es an die globale Variable jedes Mal anhängen, also warum bleibt es nicht? –

+0

Es erstellt eine Kopie des Stapels zu diesem Zeitpunkt. Selbst wenn der Stapel geändert wird, enthält die Kopie des Stapels immer noch die vorherigen Stapelwerte. Es, weil der Grund von @ Open-Source in den Kommentaren –

+0

zur Verfügung gestellt Es erstellt eine Kopie des Stapels zu diesem Zeitpunkt. Selbst wenn der Stapel geändert wird, enthält die Kopie des Stapels immer noch die vorherigen Stapelwerte.Es, weil der Grund von @ Open-Source in Kommentaren –

Verwandte Themen