0

I am writing a program that dose many math computations that eventually make a list of points to plot. I does so over several iterations and gets one point per iteration, and then uses the new point for the next iteration in the code. The list conditions_old holds the values from the last iteration. The list conditions_new are the new points that are found after an iteration is finished. At the end of the code, the lists are set equal to each other: conditions_old = conditions_new. This is the only time conditions_old is assigned a value except for the initial conditions that are used to start the calculations. With all that said, here is the problem I'm having:

conditions_old = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

kCompute = conditions_old[:]

for i in range(3):
    for j in range(3):
        print("conditions_old BEFORE: ", conditions_old[i][j])
        kCompute[i][j] = (conditions_old[i][j] + (1/4))  # This is where things get fishy.
        print("conditions_old AFTER: ", conditions_old[i][j])
        print("kCompute: ", kCompute[i][j])

This is a small portion of my code. What happens is that the list conditions_old will acquire the values of kCompute once that calculation has been made. My question is this; why is conditions_old acquiring the the new value of kCompute? Also, how do you fix this problem?

I've seen python do some odd things before, but this is something I never expected to run into.

I'm currently using python 3.4 on Yosemite

Camon
  • 1,003
  • 1
  • 10
  • 22
  • [Other](http://stackoverflow.com/questions/27629727/does-slice-only-make-shallow-copy-of-a-list) [possibilities](http://stackoverflow.com/questions/19068707/slicing-operation-give-deep-copy-or-shallow-copy). – TigerhawkT3 Aug 07 '15 at 02:44

2 Answers2

1

Note that:

kCompute = conditions_old[:]

makes a shallow copy. In your line:

kCompute[i][j] = (conditions_old[i][j] + (1/4))  # This is where things get fishy.

You're setting the value on one of the inner lists which is shared with conditions_old due to the shallow nature of your copy. In other words:

kCompute is conditions_old  # False
kCompute[0] is conditions_old[0]  # True

The easiest fix is to do a deep copy:

from copy import deepcopy

...
kCompute = copy.deepcopy(conditions_old)
mgilson
  • 300,191
  • 65
  • 633
  • 696
1

You need to make a deep copy of the original list before it has been edited.

kCompute = conditions_old[:] only makes a shallow copy, this the lists within the two lists, reference the same objects.

You can make a deep copy to avoid this issue:

from copy import deepcopy
kCompute = deepcopy(conditions_old)

From the docs:

A shallow copy constructs a new compound object and then (to the extent possible) inserts references into it to the objects found in the original.

A deep copy constructs a new compound object and then, recursively, inserts copies into it of the objects found in the original.

user3636636
  • 2,409
  • 2
  • 16
  • 31