What is the difference between [[0 for _ in the range (10)] for _ in the range (10)] and [0 for _ in the range (10)] * 10?

>>> CM = [[0 for _ in range(10)]] * 10 >>> CM [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]] >>> CM[0][0] = CM[0][0] + 1 >>> CM [[1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]] 

I tried to create a matrix of confusion. It contains mainly the number of pairs (i, j). First, I created a list of lists, and then increased the corresponding variable. However, this did not work as expected. CM [i] [0] is incremented for all values โ€‹โ€‹of i.

I found a job around.

 >>> CM = [[0 for _ in range(10)] for _ in range(10)] >>> CM [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]] >>> CM[0][0] = CM[0][0] + 1 >>> CM [[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, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]] 

But I would appreciate it if someone could explain why the first method failed.

+4
source share
1 answer
 >>> CM = [[0 for _ in range(10)]] * 10 

Copy a link to the same object ten times. This is equivalent to this:

 >>> x = [0 for _ in range(10)] >>> CM = [x, x, x, x, x, x, x, x, x, x] 

Thus, the manipulation of one element causes side effects. Your workaround is elegant and correct.

 >>> CM = [[0 for _ in range(10)]] * 10 

Copy a link to the same object ten times. This is equivalent to this:

 >>> x = [[0 for _ in range(10)]] >>> CM = [x, x, x, x, x, x, x, x, x, x] 

Thus, the manipulation of one element causes side effects. Your workaround is elegant and correct.

Note:

This happens because list items are lists (which are mutable). If they were, for example, strings that are immutable, this would not be a problem if the same string were specified in different lists, since they cannot be manipulated. Python doesn't like to waste memory (unless explicitly stated, i.e. deepcopy ), so copy lists will just copy their links.

+3
source

All Articles