Python list append
Question:
I want to store the intermediate values of a variable in Python. This variable is updated in a loop. When I try to do this with a list.append
command, it updates every value in the list with the new value of the variable. How should I do it?
while (step < maxstep):
for i in range(100):
x = a*b*c
f1 += x
f2.append(f1)
print f2
raw_input('<<')
step += 1
Expected output
[array([-2.03,-4.13])]
<<
[array([-2.03,-4.13]),array([-3.14,-5.34])]
Printed output
[array([-2.03,-4.13])]
<<
[array([-3.14,-5.34]),array([-3.14,-5.34])]
Is there a different way of getting what I want in Python?
Answers:
It appears you are appending the same array to the list, and then changing the content of the array.
You need to create a new array object each time you append it to f2
.
Assuming the original had a typo and f1
is actually fi
(or vice versa):
fi
is a pointer to an object, so you keep appending the same pointer. When you use fi += x
, you are actually changing the value of the object to which fi
points.
To solve the issue you can use fi = fi + x
instead.
I suppose you meant something like this:
f2 = []
f1 = 0
for i in range(100):
x = f()
f1 += x
f2.append(f1)
print f2
Note that if f1
is a mutable object, the line f1 += x
doesn’t create new object, but only changes value of f1
, so all its occurrences in f2
array are updated.
The object you are appending (fi) is mutable (see Python documentation), meaning, in essence, that you are appending a reference to the object, not the object value. Therefore, both list index 0 and 1 are actually the same object.
You need to either create a new object (fi = array()
) on every loop iteration or use the copy module.
Another related question is "How do I pass a variable by reference?".
Daren Thomas used assignment to explain how variable passing works in Python. For the append method, we could think in a similar way. Say you’re appending a list "list_of_values" to a list "list_of_variables",
list_of_variables = []
list_of_values = [1, 2, 3]
list_of_variables.append(list_of_values)
print "List of variables after 1st append: ", list_of_variables
list_of_values.append(10)
list_of_variables.append(list_of_values)
print "List of variables after 2nd append: ", list_of_variables
The appending operation can be thought as:
list_of_variables[0] = list_of_values --> [1, 2, 3]
list_of_values --> [1, 2, 3, 10]
list_of_variables[1] = list_of_values --> [1, 2, 3, 10]
Because the first and second item in "list_of_variables" are pointing to the same object in memory, the output from above is:
List of variables after 1st append: [[1, 2, 3]]
List of variables after 2nd append: [[1, 2, 3, 10], [1, 2, 3, 10]]
On the other hand, if "list_of_values" is a variable, the behavior will be different.
list_of_variables = []
variable = 3
list_of_variables.append(variable)
print "List of variables after 1st append: ", list_of_variables
variable = 10
list_of_variables.append(variable)
print "List of variables after 2nd append: ", list_of_variables
The appending operation now is equivalent to:
list_of_variables[0] = variable --> 3
variable --> 4
list_of_variables[1] = variable --> 4
And the output is:
List of variables after 1st append: [3]
List of variables after 2nd append: [3, 10]
The difference between variable and list_of_values is the latter one changes in-place.
I want to store the intermediate values of a variable in Python. This variable is updated in a loop. When I try to do this with a list.append
command, it updates every value in the list with the new value of the variable. How should I do it?
while (step < maxstep):
for i in range(100):
x = a*b*c
f1 += x
f2.append(f1)
print f2
raw_input('<<')
step += 1
Expected output
[array([-2.03,-4.13])]
<<
[array([-2.03,-4.13]),array([-3.14,-5.34])]
Printed output
[array([-2.03,-4.13])]
<<
[array([-3.14,-5.34]),array([-3.14,-5.34])]
Is there a different way of getting what I want in Python?
It appears you are appending the same array to the list, and then changing the content of the array.
You need to create a new array object each time you append it to f2
.
Assuming the original had a typo and f1
is actually fi
(or vice versa):
fi
is a pointer to an object, so you keep appending the same pointer. When you use fi += x
, you are actually changing the value of the object to which fi
points.
To solve the issue you can use fi = fi + x
instead.
I suppose you meant something like this:
f2 = []
f1 = 0
for i in range(100):
x = f()
f1 += x
f2.append(f1)
print f2
Note that if f1
is a mutable object, the line f1 += x
doesn’t create new object, but only changes value of f1
, so all its occurrences in f2
array are updated.
The object you are appending (fi) is mutable (see Python documentation), meaning, in essence, that you are appending a reference to the object, not the object value. Therefore, both list index 0 and 1 are actually the same object.
You need to either create a new object (fi = array()
) on every loop iteration or use the copy module.
Another related question is "How do I pass a variable by reference?".
Daren Thomas used assignment to explain how variable passing works in Python. For the append method, we could think in a similar way. Say you’re appending a list "list_of_values" to a list "list_of_variables",
list_of_variables = []
list_of_values = [1, 2, 3]
list_of_variables.append(list_of_values)
print "List of variables after 1st append: ", list_of_variables
list_of_values.append(10)
list_of_variables.append(list_of_values)
print "List of variables after 2nd append: ", list_of_variables
The appending operation can be thought as:
list_of_variables[0] = list_of_values --> [1, 2, 3]
list_of_values --> [1, 2, 3, 10]
list_of_variables[1] = list_of_values --> [1, 2, 3, 10]
Because the first and second item in "list_of_variables" are pointing to the same object in memory, the output from above is:
List of variables after 1st append: [[1, 2, 3]]
List of variables after 2nd append: [[1, 2, 3, 10], [1, 2, 3, 10]]
On the other hand, if "list_of_values" is a variable, the behavior will be different.
list_of_variables = []
variable = 3
list_of_variables.append(variable)
print "List of variables after 1st append: ", list_of_variables
variable = 10
list_of_variables.append(variable)
print "List of variables after 2nd append: ", list_of_variables
The appending operation now is equivalent to:
list_of_variables[0] = variable --> 3
variable --> 4
list_of_variables[1] = variable --> 4
And the output is:
List of variables after 1st append: [3]
List of variables after 2nd append: [3, 10]
The difference between variable and list_of_values is the latter one changes in-place.