0

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]] 
1
  • Where do you see erroneous behaviour? What do you expect in the output? Commented Dec 14, 2017 at 12:54

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

2 Comments

That is so fantastically helpful. Thank you so much!
The connection between Python names and values is somewhat confusing in the beginning. This explanation might clarify some underlying concepts in Python.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.