0

I know that similar questions have been posted on this site before, but I truly think this case is different so hear me out.

I have some simple Python code that creates a 2D list of characters (i.e. strings of length 1), tries to process the 2D list, and print it out. Here it is:

def printGrid(image):
    for row in range(len(image)):
        for col in range(len(image[row])):
            print(image[row][col], end='')
        print()
    print()


def invert(image):
    for row in range(len(image)):
        for col in range(len(image[row])):
            if image[row][col] == '.':
                image[row][col] = 'X'
            else:
                image[row][col] = '.'


grid = [['.'] * 10] * 10    # 2D square of '.'
printGrid(grid)
invert(grid)
printGrid(grid)

I was expecting the code to print out 1 square of .s and another of Xs, like this:

..........
..........
..........
..........
..........
..........
..........
..........
..........
..........

XXXXXXXXXX
XXXXXXXXXX
XXXXXXXXXX
XXXXXXXXXX
XXXXXXXXXX
XXXXXXXXXX
XXXXXXXXXX
XXXXXXXXXX
XXXXXXXXXX
XXXXXXXXXX

but instead I got 2 squares of .s, like this:

..........
..........
..........
..........
..........
..........
..........
..........
..........
..........

..........
..........
..........
..........
..........
..........
..........
..........
..........
..........

After trying to debug for a while, I found that if I commented out the else block in the invert function, then I get the expected output (you can try running the code for yourself to see). This led me to conclude that both the if block AND the else block are executed. Does anyone know why this may be happening? (I'm using Python 3.6.1 btw)

P.S. I discovered that this bug apparently only appears for certain grid sizes. For example, if the size of grid is 5, 7 or 9, then the output is as expected. But if it's something like 6, 8 or 10, then the output is not as expected (apparently the bug only occurs for even-numbers of size?).

Saeed Baig
  • 1,197
  • 12
  • 13
  • 1
    `['.'] * 10` creates a single list. When you then do ` * 10` to it, you now have 10 references to the same exact list. I don't mean a list with the same items in it; it's the same place in memory. When you then assign something in that list, it affects the entire outer list. What you need is to make a bunch of lists: `[['.'] * 10 for _ in range(10)]` – zondo May 11 '18 at 02:18
  • @zondo oh ok well your fix definitely does work and gives the output I was expecting, so thanks for that. Though I'm still confused as to why it was working with odd-sized squares (e.g. 9 by 9, 7 by 7) and not even-sized ones. – Saeed Baig May 11 '18 at 04:11

0 Answers0