1

While writing a code snippet for a Leetcode question, I noticed that my Python3 arrays were not getting updated as expected.

Basically, I have a 2D array listing players moves for a tic-tac-toe game. Player A plays first, Player B next, Player A next, and so on. My first move is to represent these moves on a 2D array. The array moves listed below mentions the (x,y) co-ordinates of the 3x3 TicTacToe grid that is to be updated.

(0,0)  |  (0,1)  |  (0,2)
_______|_________|________
 (1,0) |  (1,1)  |  (1,2)
       |         |
_______|_________|________
(2,0)  |   (2,1) |  (2,2)
       |         |
moves = [[0,0],[2,0],[1,1],[2,1],[2,2]]
arr=[['']*3]*3
#print(arr)
for i in range(len(moves)):
    xC=moves[i][0]
    yC=moves[i][1]
    if(i%2==0):
        #playerA
        arr[xC][yC]='X'
    else:
        #playerB
        arr[xC][yC]='O'  
print(arr)

The variable 'moves' lists the population of only 5 boxes out of 9 boxes in the tic tac toe game, but the output array 'arr' is populated as such:

[['O', 'O', 'X'], ['O', 'O', 'X'], ['O', 'O', 'X']]

Just fyi: I've been using Py3 for a few years now, and I'm comfortable with it (not a newbie). What's your thoughts on the issue? A bug in Py3's array module? Let me know. (btw, my first StackOverflow Question!)

The question is at this address: https://leetcode.com/problems/find-winner-on-a-tic-tac-toe-game/

1 Answers1

3

The problem with your code is in the line arr=[['']*3]*3. It seems like you're creating three different lists of empty strings, but you're actually creating three references to the same list - that's what list multiplication does in python. When you change one list, they all change because they are all the same list.

Your code would run as expected if you replace the mentioned line with arr = [['']*3 for _ in range(3)]. This list comprehension will actually create three unrelated lists. Note that you're still creating three references to the same string in each list, as multiplication is still used - but that's okay because string are immutable in python, so it doesn't really matter.

chuck
  • 1,420
  • 4
  • 19
  • Thanks very much @chuck2002 ! The program now works when i replace the array instantiation with your approach. If you don't mind, could you guide me to some deep-dive docs/ best practices guide for Py3? I'd like to avoid such pitfalls in future. – Aswin Tekur Mar 09 '20 at 11:03
  • @AswinTekur I actually didn't learn from any great sources that I can recommend specifically. From my experience the best way to improve is to try, fail, find the bug and fix it. Just keep doing that and google whenever you're confused about something – chuck Mar 09 '20 at 11:05
  • I was trying to write a similar answer, but had to go afk for a while :D Either way, have a look at https://stackoverflow.com/questions/986006/how-do-i-pass-a-variable-by-reference, which describes some of the mutability/immutability issues that happened in your code. – janus235 Mar 09 '20 at 11:23