Двумерные списки в Python: полное руководство

Раздел: Структуры данных -> Списки и массивы

Двумерные списки в Python: создание и обработка

Двумерные списки (матрицы) представляют собой списки, элементами которых являются другие списки. Это основная структура для хранения табличных данных в Python без использования сторонних библиотек.

Основной эффективный способ: list comprehension

Для создания двумерного списка заданного размера с одинаковыми начальными значениями применяют вложенный генератор списков. Например, для матрицы 3x4 из нулей:

matrix = [[0 for j in range(4)] for i in range(3)]

минимальный элемент массива python (поиск минимального элемента в массиве)

Внешний цикл for i in range(3) создаёт строки, внутренний for j in range(4) заполняет каждую строку нулями. Каждая строка создаётся независимо, поэтому изменение одного элемента не затрагивает другие строки.

Как создать двумерный список с помощью вложенных циклов?

Для начинающих может быть нагляднее явное создание пустого списка и добавление строк в цикле:

matrix = []
for i in range(3):
    row = []
    for j in range(4):
        row.append(0)
    matrix.append(row)

массив python примеры (примеры массивов в python)

Этот способ даёт тот же результат, но менее компактен. Используется, когда логика заполнения сложнее и требует дополнительных условий.

Как создать список с помощью умножения и почему это может быть опасно?

Краткая запись [[0]*4]*3 создаёт три ссылки на один и тот же список строк. При изменении одного элемента меняются все строки:

matrix = [[0]*4]*3
matrix[0][0] = 5
print(matrix)  # [[5,0,0,0],[5,0,0,0],[5,0,0,0]]

списки в python примеры (примеры работы со списками в python)

Эта ошибка часто встречается у новичков. Правильный способ - использовать list comprehension: [[0]*4 for _ in range(3)], где внутренний список создаётся заново на каждой итерации.

Как создать зубчатый список (с разной длиной строк)?

Двумерные списки не обязаны быть прямоугольными. Строки могут иметь разную длину:

jagged = [[1,2], [3,4,5], [6]]

Такой список создаётся просто перечислением вложенных списков. Доступ к элементу третьей строки: jagged[2][0] вернёт 6. При этом нужно учитывать, что не все строки имеют одинаковое количество столбцов.

Типичные ошибки при работе с двумерными списками

  • IndexError при обращении по несуществующему индексу. Всегда проверяйте длину списка len(matrix) и длину строки len(matrix[i]).
  • Путаница осей: часто путают строку и столбец. Помните, что первый индекс - номер строки, второй - столбца.
  • Поверхностное копирование: при использовании copy.copy() или среза matrix[:] копируется только внешний список, а внутренние остаются общими. Для полного независимого копирования применяйте copy.deepcopy().
  • Изменение строки через присваивание новой длины: matrix[i] = [0]*n - допустимо, но теряется старая строка.

Расширенные примеры работы с двумерными списками

Ниже приведены продвинутые примеры, демонстрирующие различные операции с матрицами.

Транспонирование матрицы

Преобразование строк в столбцы. Компактный способ через вложенный list comprehension:

Пример
matrix = [[1,2,3], [4,5,6]]
transposed = [[row[i] for row in matrix] for i in range(len(matrix[0]))]
print(transposed)
[[1, 4], [2, 5], [3, 6]]

Альтернатива с использованием zip и map:

Пример
transposed = list(map(list, zip(*matrix)))
print(transposed)
[[1, 4], [2, 5], [3, 6]]

Функция zip(*matrix) собирает элементы с одинаковыми индексами в кортежи, а map(list, ...) преобразует их обратно в списки.

Умножение матриц

Стандартный алгоритм с тремя вложенными циклами:

Пример
def matrix_mult(A, B):
    n, m = len(A), len(A[0])
    p = len(B[0])
    result = [[0]*p for _ in range(n)]
    for i in range(n):
        for j in range(p):
            for k in range(m):
                result[i][j] += A[i][k] * B[k][j]
    return result

A = [[1,2],[3,4]]
B = [[5,6],[7,8]]
print(matrix_mult(A, B))
[[19, 22], [43, 50]]

Проверьте, что количество столбцов в A равно количеству строк в B.

Обход матрицы по спирали

Вывод элементов в порядке спирали (право, вниз, лево, вверх):

Пример
def spiral_order(matrix):
    if not matrix: return []
    result = []
    top, bottom, left, right = 0, len(matrix)-1, 0, len(matrix[0])-1
    direction = 0
    while top <= bottom and left <= right:
        if direction == 0:  # вправо
            for i in range(left, right+1):
                result.append(matrix[top][i])
            top += 1
        elif direction == 1:  # вниз
            for i in range(top, bottom+1):
                result.append(matrix[i][right])
            right -= 1
        elif direction == 2:  # влево
            for i in range(right, left-1, -1):
                result.append(matrix[bottom][i])
            bottom -= 1
        else:  # вверх
            for i in range(bottom, top-1, -1):
                result.append(matrix[i][left])
            left += 1
        direction = (direction + 1) % 4
    return result

m = [[1,2,3],[4,5,6],[7,8,9]]
print(spiral_order(m))
[1, 2, 3, 6, 9, 8, 7, 4, 5]

Генерация шахматного узора

Создание матрицы с чередованием 0 и 1 как на шахматной доске:

Пример
def chessboard(rows, cols):
    return [[(i+j)%2 for j in range(cols)] for i in range(rows)]

board = chessboard(5,5)
for row in board:
    print(row)
[0, 1, 0, 1, 0]
[1, 0, 1, 0, 1]
[0, 1, 0, 1, 0]
[1, 0, 1, 0, 1]
[0, 1, 0, 1, 0]

Сумма элементов на диагоналях

Вычисление суммы главной и побочной диагоналей квадратной матрицы:

Пример
def diagonal_sum(matrix):
    n = len(matrix)
    main = sum(matrix[i][i] for i in range(n))
    anti = sum(matrix[i][n-1-i] for i in range(n))
    return main, anti

m = [[1,2,3],[4,5,6],[7,8,9]]
print(diagonal_sum(m))
(15, 15)

Поворот матрицы на 90 градусов по часовой стрелке

Комбинация транспонирования и отражения по горизонтали:

Пример
def rotate_clockwise(matrix):
    n = len(matrix)
    transposed = [[matrix[j][i] for j in range(n)] for i in range(n)]
    rotated = [row[::-1] for row in transposed]
    return rotated

m = [[1,2],[3,4]]
print(rotate_clockwise(m))
[[3, 1], [4, 2]]

Глубокое копирование матрицы

Чтобы избежать случайного изменения данных при передаче в функцию, используйте copy.deepcopy:

Пример
import copy
matrix = [[1,2],[3,4]]
shallow = matrix[:]
deep = copy.deepcopy(matrix)
matrix[0][0] = 99
print('shallow:', shallow)
print('deep:', deep)
shallow: [[99, 2], [3, 4]]
deep: [[1, 2], [3, 4]]

Поверхностная копия (срез) копирует ссылки на внутренние списки, поэтому изменение отражается в shallow. Глубокое копирование создаёт полностью независимые объекты.

Двумерные списки в Python - comments

En
двумерные списки в python (python)