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?

Asked By: abcd

||

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.

Answered By: John La Rooy

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.

Answered By: zenpoy

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.

Answered By: Abgan

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.

Answered By: Erik Cederstrand

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.

Answered By: Gatsby
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.