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?
Answers:
You have to copy stack to the var_global instead of appending a reference.
var_gobal.append(stack.copy())
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']]
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']]
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
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?
You have to copy stack to the var_global instead of appending a reference.
var_gobal.append(stack.copy())
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']]
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']]
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