0

I am thoroughly perplexed over the following behavior:

  gap_in_y[i][j] = max((scoreMatrix[i-1][j] - dy), (gap_in_y[i-1][j] - ey))
  if i == 3 and j == 1:
    print gap_in_y
  gap_in_x[i][j] = max((scoreMatrix[i][j-1] - dx), (gap_in_x[i][j-1] - ex))
  if i == 3 and j == 1:
    print gap_in_y

The two print statements produce arrays that are different in exactly one value: the value contained in gap_in_y[3][1]. Modifying gap_in_x, a separate array, shouldn't affect gap_in_y... but, somehow it does.

Any ideas? I've been going crazy trying to figure this out!

I created the two arrays in the following manner:

for i in range (0, ALength+1):
    for j in range (0, BLength+1):
        new.append("N/A")
    gap_in_y.append(new)
    gap_in_x.append(new)
    new = []
2
  • How were gap_in_x & gap_in_y created? What happened to gap_in_x between the two print statements? Commented Oct 1, 2012 at 23:55
  • just assigning a value to gap_in_x! Commented Oct 2, 2012 at 0:04

5 Answers 5

2

It is hard to tell without seeing how gap_in_y and gap_in_x are created, but what is probably happening here is that gap_in_y[3] and gap_in_x[3] are both references to the same list, so modifying one will modify the other. You can check this out by adding the following code:

if i == 3:
    print id(gap_in_y[3]) == id(gap_in_x[3])

If this ever prints True, then you know that you have copies of the same list in both of your nested lists.

Sign up to request clarification or add additional context in comments.

1 Comment

it did print True - I added in my code for creating the two arrays.
0

When you do:

gap_in_x.append(new)
gap_in_y.append(new)

both lists will reference the same object new.

The simplest solution might be to change this to:

gap_in_x.append(new[:])
gap_in_y.append(new[:])

(assuming new is a list).

The slice operator [:] will create a copy of list new so each list will receive its own copy.

2 Comments

In this case the list is also a new empty list, so in fact you don't need to make a copy of an empty list, just append a new empty list .append([]).
Keith, note that new sometimes has the value 'N/A' in it.
0

I see, when you created the array, you create a single new list, and append this same list into both the gap_in_x and gap_in_y lists. So they now contain the same list and any mutation in it will naturally be seen from either parent list.

Comments

0

Instead of appending new, append new[:], this will create a copy of new for each gap_in_*, as you have it now, it puts the same list into each of them.

for i in range (0, ALength+1):
    for j in range (0, BLength+1):
        new.append("N/A")
    gap_in_y.append(new[:])
    gap_in_x.append(new[:])
    new = []

Comments

0

Other answers have pointed out the issue with the current code. I just want to suggest an alternative way of creating your lists, using list multiplication and a list comprehension rather than explicit loops and append():

gap_in_x = [["N/A"] * (BLength + 1) for _ in range(ALength + 1)]
gap_in_y = [["N/A"] * (BLength + 1) for _ in range(ALength + 1)]

Note that you don't want to use list multiplication for the outer list (e.g. [["N/A"] * BLength] * ALength) because this will cause a similar issue to what you're having already, where all of the inner lists will be copies of each other (though within the same outer array this time, not across the two). It's fine for the inner list because strings are immutable. It doesn't matter if some (or all) of the N/As reference the same object, since that object cannot modified.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.