Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Append is overwriting existing data in list

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?

like image 621
Belphegor21 Avatar asked Mar 22 '17 14:03

Belphegor21


People also ask

Does append overwrite in Python?

Appends to a file and creates the file if it does not exist or overwrites an existing file.

Does append overwrite a file?

To append text to a file means adding text to the end of a file without overwriting the file content.

What happens if you append a list to a list?

append() adds a list inside of a list. Lists are objects, and when you use . append() to add another list into a list, the new items will be added as a single object (item).

What is overwrite append?

The append option, which is the default option, adds the copied data to the existing data for the target members. The overwrite option takes the copied data and replaces the existing data for the target members.


1 Answers

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']]

like image 87
student Avatar answered Oct 15 '22 18:10

student