← Все вопросы

Как создать двумерный список (матрицу) в Python?

Задан 1 месяц назад202 просмотров2 ответа
11

Хочу сделать таблицу/матрицу — список списков, например сетку 3 на 3 из нулей. Попробовал [[0]*3]*3, заполнил, а у меня меняются сразу все строки! Что я делаю не так и как создать матрицу правильно?

2 ответа

15
✓ Принятый ответ — помог автору

Вы наткнулись на классическую ловушку. [[0]*3]*3 создаёт три ссылки на ОДИН и тот же внутренний список, поэтому изменение одной «строки» меняет все:

grid = [[0]*3]*3
grid[0][0] = 5
print(grid)   # [[5,0,0],[5,0,0],[5,0,0]] — испортились все!

Внешний *3 копирует не сам список, а ссылку на него.

Правильно — создавать каждую строку отдельно через генератор списка:

rows, cols = 3, 3
grid = [[0]*cols for _ in range(rows)]

grid[0][0] = 5
print(grid)   # [[5,0,0],[0,0,0],[0,0,0]] — верно!

Здесь for _ in range(rows) на каждой итерации создаёт новый список [0]*cols, поэтому строки независимы. Внутренний [0]*cols безопасен, потому что числа неизменяемы — там ловушки нет.

Обход матрицы:

for r in range(rows):
    for c in range(cols):
        grid[r][c] = r * cols + c

или по значениям:

for row in grid:
    for value in row:
        print(value, end=' ')
    print()

Запомните правило: * для вложенных изменяемых объектов копирует ссылку, а не данные. Для матриц всегда используйте генератор [... for _ in range(n)].

5

Если матрицы большие и предстоят числовые операции (умножение, транспонирование), удобнее NumPy:

import numpy as np
grid = np.zeros((3, 3))   # матрица 3x3 из нулей

NumPy сразу даёт удобную индексацию grid[0, 1], быстрые операции над всей матрицей и никакой ловушки со ссылками. Но для учебных задач и небольших таблиц обычный список списков через генератор — самое то, без лишних зависимостей.

Ваш ответ

Войдите, чтобы ответить на вопрос.