0

I'm using Python 3 and with this code:

import random
mat = [[0]*5]*5

for i in range (0,5) :
    for j in range (0,5)  :
        mat[i][j] = random.randint(10,50)

print (mat)

I'm getting results like this:

[[26, 10, 28, 21, 15], [26, 10, 28, 21, 15], [26, 10, 28, 21, 15], [26, 10, 28, 21, 15], [26, 10, 28, 21, 15]]

The rows are equal each other, but the loop seems to be alright.

What is the problem?

2 Answers2

4

Because all the inner lists are actually copies of same object, so modifying one of them will automatically affect other lists as well.:

>>> l = [[0]*5]*5
>>> [id(x) for x in l]
[155011468, 155011468, 155011468, 155011468, 155011468]

Same IDs means all indexes actually point to same object inside the list:

>>> l[0][0] = 1  #modifying one, changes all of them
>>> l
[[1, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0]]

Use a list comprehension to fix this issue:

>>> l = [[0]*5 for _ in xrange(5)]
>>> [id(x) for x in l]               #all lists are unique now
[155710028, 155710764, 155710700, 155710732, 155709996]

Works as expected:

>>> l[0][0] = 1
>>> l
[[1, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504
1

The problem is this line:

mat = [[0]*5]*5

What that does is to create a single list of 5 zeros ([0]*5) and then create 5 more references to that same list.

The solution which gets you around this problem:

mat = [[0]*5 for _ in xrange(5)]

this creates a list of 5 zeros 5 separate times meaning that all the lists are independent.

mgilson
  • 300,191
  • 65
  • 633
  • 696