ArthurDent
ArthurDent

Reputation: 179

Python - Appending list to another list

I am try to code a game which has a 3x3 grid (think noughts & crosses [US=Tic Tac Toe]).

Each cell has a weighting. When the player places a counter a score is calculated. I want my code to go through the 3x3 matrix and find the top score and return the co-ordinates of the cell where that top score is found (this works) - but if there are several cells with an equal top score I want to return a list containing each of the places where that score is found.

Here is a cut-down version of my code (with LOTS of print statements to try to work out why it's not working).

The intention is that the loop records a simple list ("pos") which has the row and column co-ordinates (e.g. [0][2]) and appends this to a running list of equal scores ("possibles")

If instead of trying to append a 2-entry list I put in a single random number, the overall list ("possibles") builds as expected, but appending the 2-entry list results in a duplicated list of the final position (see output).

I clearly have a logic problem, but I am new to Python. Can anyone show me where I have gone wrong?

def test():
val = 1
max_val = 0
possibles = [] # This is the list where I will store a list of equally weighted positions
pos = [] # This is simply a 2 number co-ordinate
pos.append("") # Get it ready for row & col references
pos.append("")
for row in range (0,3):
    for col in range (0,3):
        print("Testing row",row,"col",col)
        print("Possibles so far",possibles)
        print("Pos=",pos)
        pos[0] = row
        pos[1] = col
        print("Now pos=",pos)
        #possibles.append(randint(0,100)) # This works
        possibles.append(pos) # This doesn't
print("List of equals",possibles)

test()

Output:

Testing row 0 col 0
Possibles so far []
Pos= ['', '']
Now pos= [0, 0]
Testing row 0 col 1
Possibles so far [[0, 0]]
Pos= [0, 0]
Now pos= [0, 1]
Testing row 0 col 2
Possibles so far [[0, 1], [0, 1]]
Pos= [0, 1]
Now pos= [0, 2]
Testing row 1 col 0
Possibles so far [[0, 2], [0, 2], [0, 2]]
Pos= [0, 2]
Now pos= [1, 0]
Testing row 1 col 1
Possibles so far [[1, 0], [1, 0], [1, 0], [1, 0]]
Pos= [1, 0]
Now pos= [1, 1]
Testing row 1 col 2
Possibles so far [[1, 1], [1, 1], [1, 1], [1, 1], [1, 1]]
Pos= [1, 1]
Now pos= [1, 2]
Testing row 2 col 0
Possibles so far [[1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2]]
Pos= [1, 2]
Now pos= [2, 0]
Testing row 2 col 1
Possibles so far [[2, 0], [2, 0], [2, 0], [2, 0], [2, 0], [2, 0], [2, 0]]
Pos= [2, 0]
Now pos= [2, 1]
Testing row 2 col 2
Possibles so far [[2, 1], [2, 1], [2, 1], [2, 1], [2, 1], [2, 1], [2, 1], [2, 1]]
Pos= [2, 1]
Now pos= [2, 2]
List of equals [[2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2]]

Upvotes: 0

Views: 1721

Answers (1)

Mr. T
Mr. T

Reputation: 12410

You append the same object pos over and over again to your list. If you change its value in the next loop, all its representations are changed as well. You can test this. Append at the end of your test function:

  for item in possibles:
         print(item, id(item))

See, all list items have the same id.

To avoid this, assign a new object in each loop:

def test():
    possibles = [] 
    for row in range (3):
        for col in range (3):
            pos = [row, col]           #create a new list
            print("Now pos=",pos)
            possibles.append(pos)      #and append this new element
    print("List of equals",possibles)

test()

It looks similar, but instead of changing element [0] and [1] of an existing list pos, now in each loop a new list is created. If you check it with id(item) from above, all list elements of possibles have now a different id.

Upvotes: 1

Related Questions