2

I have met a very strange issue. I use a multi-dimension list to store some data. The data are in a .txt file, every line has 9 digit, and it has 450 lines data. For every 9 lines data(a 9x9 digit grid), I want to group them as a sublist. I use the code below to store the data, and my problem is when I finished and print the multi-dimension list, it seems every line of data in the list are the same. Sorry for my poor description, maybe my code can tell everything, and please tell me what's wrong with the code. I use python 2.7.5 on Windows, thanks.

# grid is a 3-dimension list, the first dimension is the index of 9x9 digit subgrid
# there are 50 9x9 digit subgrid in total.  
grid = [[[0]*9]*9]*50

with open('E:\\sudoku.txt', 'r') as f:
    lines = f.readlines()
    for line_number, line in enumerate(lines, 1):
        # omit this line, it is not data
        if line_number % 10 == 1:
            continue
        else:
            for col, digit in enumerate(line[:-1]):
                if line_number % 10 == 0:
                    x = line_number / 10 - 1
                    y = 8
                else:
                    x = line_number / 10
                    y = line_number % 10 - 2
                grid[x][y][col] = int(digit)

                # I print all the digits in the list and compare them with the .txt file
                # it shows every single cell in grid are set correctly !!
                print 'x=%d, y=%d, z=%d, value=%d '% (x, y, col, grid[x][y][col])

# But strange thing happens here
# I only get same line of value, like this:
# [[[0, 0, 0, 0, 0, 8, 0, 0, 6], [0, 0, 0, 0, 0, 8, 0, 0, 6] ... all the same line
# and 000008006 happens to be the last line of data in the .txt file
# what happens to the rest of data ? It's like they are all overwritten by the last line  
print grid
colin
  • 281
  • 4
  • 13
  • Just a note: whenever you find yourself using nested lists to represent two- and more-dimensional arrays, you should really consider using ``numpy``. – fjarri Oct 12 '13 at 08:44
  • Just a note: If you can do something easily with built-in lists (no matter of which dimension), do not consider using `numpy`. Don't shoot sparrows with cannons. – Hyperboreus Oct 12 '13 at 08:45

2 Answers2

4

The list multiplication does not clone (or create new) objects, but simply references the same (in your case mutable) object various times.

See here:

a = [[3]*3]*3
print(a)
a[0][1] = 1
print(a)
Hyperboreus
  • 31,997
  • 9
  • 47
  • 87
0

grid = [[[0]*9]*9]*50 does not create 50 of 9x9 grid. When you state [[[0]*9]*9]*50, python creates 9 reference of [0].

List multiplication only creates new references of the same object, in other words, every single list you made refer to the same place in the memory, used to store the [0] list.

A similiar question.

Community
  • 1
  • 1
aIKid
  • 26,968
  • 4
  • 39
  • 65
  • 2
    The `[0]*9` is exactely the part which does NOT hurt. As integers as immutable this piece of code works perfectly. The pain begins in the outer multiplications. – Hyperboreus Oct 12 '13 at 08:47
  • Thanks, the link you mentioned here explain the problem very good, really appreciate it. – colin Oct 12 '13 at 08:56