0

Currently I am trying to place a word in a column of 2D array in Python 3.6

    def __init__(self) -> None:
        self.board = [["."] * 10] * 10
        self.board[0][0] = 'T'

    def printBoardToTerminal(self):
        for index in range(0,10):
            print()
            print(self.board[index], end=" ")

Expected:

['T', '.', '.', '.', '.', '.', '.', '.', '.', '.']
['.', '.', '.', '.', '.', '.', '.', '.', '.', '.']
['.', '.', '.', '.', '.', '.', '.', '.', '.', '.']
['.', '.', '.', '.', '.', '.', '.', '.', '.', '.']
['.', '.', '.', '.', '.', '.', '.', '.', '.', '.']
['.', '.', '.', '.', '.', '.', '.', '.', '.', '.']
['.', '.', '.', '.', '.', '.', '.', '.', '.', '.']
['.', '.', '.', '.', '.', '.', '.', '.', '.', '.']
['.', '.', '.', '.', '.', '.', '.', '.', '.', '.']
['.', '.', '.', '.', '.', '.', '.', '.', '.', '.']

Actual:

['T', '.', '.', '.', '.', '.', '.', '.', '.', '.']
['T', '.', '.', '.', '.', '.', '.', '.', '.', '.']
['T', '.', '.', '.', '.', '.', '.', '.', '.', '.']
['T', '.', '.', '.', '.', '.', '.', '.', '.', '.']
['T', '.', '.', '.', '.', '.', '.', '.', '.', '.']
['T', '.', '.', '.', '.', '.', '.', '.', '.', '.']
['T', '.', '.', '.', '.', '.', '.', '.', '.', '.']
['T', '.', '.', '.', '.', '.', '.', '.', '.', '.']
['T', '.', '.', '.', '.', '.', '.', '.', '.', '.']
['T', '.', '.', '.', '.', '.', '.', '.', '.', '.']

I thought it was a printing error but when I print(self.board) it also shows that the first element in each row is 'T'.

Edit: I tried doing the same above with the numpy library instead creating a 2D array of characters and then the replacement works as expected but with the above implementation still not sure whats going on there :/

sniperd
  • 5,124
  • 6
  • 28
  • 44

1 Answers1

1

This is because list multiplication [] * n does not create new data, but pseudo copies the list as a reference. Use list comprehension:

self.board = [["." for a in range(10)] for b in range(10)]

Using [["."] * 10] * 10 does not create new data, but copies the reference to the list ["."] 10 times


Edit as pointed out by ShadowRanger

The following is also acceptable:

self.board = [["."] * 10 for x in range(10)]
Freddy Mcloughlan
  • 4,129
  • 1
  • 13
  • 29
  • 1
    Note: The innermost `list` can be produced by multiplication here, so `[["."] * 10 for i in range(10)]` works just fine. Multiplying any sequence containing *mutable* inner values is the problem, but since the innermost `list` contains immutable `str`, it's okay. – ShadowRanger Apr 19 '22 at 04:53
  • Ah I see that makes more sense, thank you! – Spanya Shamasa Apr 20 '22 at 15:10