Append is overwriting existing data in list

Question:

I have a python program which is supposed to append list to a global variable, but instead of appending it is overwriting the list. This a demo function I made which works in the same way:

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)

The expected output should be

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

But instead i get

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

The first element of the list is overwritten. Why is this happening?

Asked By: Belphegor21

||

Answers:

You have to copy stack to the var_global instead of appending a reference.

var_gobal.append(stack.copy())
Answered By: Patrik Polakovic

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']]
Answered By: Ajay Singh

You can use slice stack = stack[:] + [element["a"]] instead of append method of list:

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)

Output:

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

Or, using stack = stack + [element["a"]] would give same result as well.

To see the difference, we can see following example:

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

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

global_var

This outputs global_var as [['a', 'b'], ['a', 'b']].

Although, tmp is appended to global_var in every iteration through my_list, on every append all referencing (or all that are pointing) to tmp is changed. Instead if slice or + is used, new list is created with all the elements in first since [:] is used:

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

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

global_var

This results: [['a'], ['a', 'b']]

Answered By: niraj

It’s because of scope of the variable you are using, You can use copy.deepcopy(my_dict) so that it won’t override the data you are inserting into the list

Answered By: Siva Bhargava
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.