简体   繁体   中英

Python: Basic operation of a list of lists

I admit i am confused by how lists of lists behave and i have written numerous sample programs and poured over documentation questions and can't figure it out.

I am looking at combining four choices from among up to 40 into unique combinations (from a math point of view). At run time i read in a list of options (changes every run) and need to construct a table (using a list of lists) that is X by X where X = number of options. I need to construct my list of lists realtime, load each position in each list with an initial value of 0 and then go forward.

I start off by constructing a blank list that is the proper length and loading it with 0's. Then i append that blank list to my scores list as many times as necessary. So now theoretically i have a list that contains 28 occurrences of a list that that has a 0 in each of 28 positions.

What is don't get if i try to change one value in one position (sort of one column, one row) in the big list (say position [2][2]) why position 2 changes in every member of the list. Something pretty basic here about how lists behave that i am missing.

Thanks for your help.


blank = []
counter = 0
while counter < 28:
    blank.insert(counter,0)
    counter +=1

print("Blank = ", blank)
scores = []
counter = 0
while counter < 28:
    scores.append(blank)
    counter +=1

print("Array built", scores)

scores[2][2] = 2

print("array changed", scores)one position in one row

You see this code:

while counter < 28:
    scores.append(blank)
    counter +=1

You are adding the same list blank 28 times. All those 28 lists are the same one.
Logically, if you do scores[2][2] = 2 , it will change the list number 3 and column number 3, but since it's the same list everywhere, they will all "change".

What you need to do is create 28 different lists, so that it works.

This is because of the blank list that you are appending to score list. The score list actually points to the reference of the blank list. If you'd have noticed, the blank list would also be changed.

Try This

scores=[[0,0,0,0],[0,0,0,0],[0,0,0,0]]
scores[2][2]=2

The answers by @Haytam and @AnantKumar are correct with respect to why all lists are being changed; all lists have the same reference, as can be seen by running id(blank) in each iteration.

What about something like this:

import numpy as np

scores = np.repeat(0, 28**2).reshape(28, 28)

This will create an ndarray of 28 arrays all filled with 28 zeros, of which a specific value can be changed, as you're attempting to do.

Verification:

The change can be verified as:

scores[2][2] = 2
sum(sum(scores))
>>> 2

Use this piece of code:

while counter < 28:
    scores.append(blank.copy())
    counter +=1

When you write scores.append(blank) it adds the same list (in memory) 28 times hence changing one instance will change all instances as all point to the same memory space. .copy() allows you to append a copy of the list. Each having a different memory reference.

We get this output on running your code with .copy() (replacing 28 with 5):

array changed [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 2, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM