0

I have the following code:

distances = [[100001] * 2] * 2
    for edge in edges:
        print(distances)
        distances[edge[0]][edge[1]] = edge[2]
        print(distances)
        print("\n")

edges is the following list of tuples:

edges = [(0, 1, 10), (1, 0, -9)]

I'm expecting this output:

[[100001, 100001], [100001, 100001]]
[[100001, 10], [100001, 100001]]

[[100001, 10], [100001, 100001]]
[[100001, 10], [-9, 100001]]

but I'm getting this output:

[[100001, 100001], [100001, 100001]]
[[100001, 10], [100001, 10]]

[[100001, 10], [100001, 10]]
[[-9, 10], [-9, 10]]

Any ideas what's wrong?

Tyler
  • 2,579
  • 2
  • 22
  • 32

1 Answers1

1

Try this code:

>>> distances[0] is distances[1]

You will get True. It means that they are the same objects so when you modify distances[0] you will modify distances[1] as well. Because distances[0] IS distances[1] they cannot be different.

How to avoid it? Simply change your code to:

distances = [[100001] * 2] + [[100001] * 2] 

Now distances[0] and distances[1] are two completely different objects so you can modify one without modifying another in the same time.

Now you may wonder why 2*list is different than list+list. It can be simply explained:

Lests assume that you have 2 lists:

a = [100001, 100001]
b = [100001, 100001]
c = a

It is obvious that when you modify a you will not modify b. However modifying a will modify the value in c because a IS c.

Now if you define distances in your way:

distances = a*2 # You will simply get [a, a] 
#so distances[0] cannot be different than distances[1] 

If you define distances in my way:

distances = a+b # you will get [a, b]
Piotr Dabkowski
  • 5,661
  • 5
  • 38
  • 47
  • Ah, makes sense. God I hate Python and how everything is just a pointer to something else... – Tyler Apr 06 '14 at 21:57