массив python 2d, печать отдельных элементов внутри цикла назначения отличается от печати всего массива

#python #python-3.x

Вопрос:

Я столкнулся с очень странной проблемой python, код ниже. Я ввожу сетку (2d массив) [[7, 8, 9], [4, 5, 6], [1, 2, 3]]

 from typing import List

def test(
        height: int,
        width: int,
        grid: List[List[int]]):

    print(grid)

    refList = [[0]*width]*height
    for h in range (0, height):
        for w in range (0, width):
            if h == 0 and w == 0:
                refList[h][w] = grid[h][w]
            elif(h < 1):
                refList[h][w] = refList[h][w-1]  grid[h][w]
            elif(w < 1):
                refList[h][w] = refList[h-1][w]   grid[h][w]
            else:
                refList[h][w] = grid[h][w]   max(refList[h-1][w], refList[h][w-1])
            print(refList[h][w])
    
    print(refList)

grid = [[7,8,9],[4,5,6],[1,2,3]]
test(3,3,grid)
 

Я ожидаю результата
[[7,15,24],[11,20,30],[12,22,33]] .
как вы можете видеть ниже, функция печати внутри цикла печатает правильные ответы, но после завершения цикла и печати всего списка она дала мне следующее
[[12, 22, 33], [12, 22, 33], [12, 22, 33]] — в основном все в верхнем ряду.

 [[7, 8, 9], [4, 5, 6], [1, 2, 3]]
7
15
24
11
20
30
12
22
33
[[12, 22, 33], [12, 22, 33], [12, 22, 33]]
 

Что здесь происходит и как я могу это исправить?

Ответ №1:

Вы экспериментируете с проблемой из-за неглубоких копий. Вы должны использовать:

 refList = [[0 for i in range(width)] for j in range(height)]
 

в замене вашей текущей строки инициализации:

 refList = [[0]*width]*height
 

Действительно, эта последняя строка создает массив ссылок на один и тот же линейный массив внутри ( [[0]*width] ). Вы можете легко проверить это, используя следующий код:

 refList = [[0]*3]*3
print(refList[0] is refList[1])  # Print True