Двумерные массивы в Python

Питон

Нередко в задачах приходится хранить прямоугольные таблицы с информацией. Их принято называть двумерными массивами или матрицами. В языке программирования Python программист может представить таблицу в виде списка строк, каждый элемент которого тоже выступает списком (к примеру, чисел).

Приведем пример создания числовой таблицы, состоящей из трех столбов и двух строк:

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

В примере первая строка списка A[0] представляет собой список из чисел [1, 2, 3]. То есть A[0][0] == 1, значение A[0][1] == 2, A[0][2] == 3, A[1][0] == 4, A[1][1] == 5, A[1][2] == 6.

Обычно для обработки и вывода списка применяется два вложенных цикла: по номеру строки и по элементам внутри строки.

Пример вывода двумерного числового списка на экран по строкам (числа разделены внутри одной строки с помощью пробелов):

for i inrange(len(A)):
for j inrange(len(A[i]):
print(A[i][j], end=’ ‘)
print()

Такой же пример, но циклы по значением списка, а не по индексу:

forrowin A:
foreleminrow:
print(elem, end=’ ‘)
print()

Пример вывода одной строки с помощью метода join:

forrowin A:
print(‘ ‘.join(list(map(str, row))))

Чтобы суммировать все числа в списке, применяем два вложенных цикла:

S = 0
for i inrange(len(A)):
for j inrange(len(A[i])):
S += A[i][j]

Такой же пример, только по значением строк:

S = 0
forrowin A:
foreleminrow:
S += elem

Создание вложенных списков

Например, даны два числа: n – количество строк и m – количество столбцов. Нужно создать список размером n×m, заполнив его нулями:

Очевидное решение получилось неверным:

# Неправильно
A = [[0] * m] * n

Чтобы убедиться в этом, достаточно присвоить значение 1 элементу A[0][0], после чего вывести значение другого элемента A[1][0], которое тоже будет 1. Все потому, что 0] * m возвращает ссылку на список из m нулей. Однако дальнейшее повторение данного элемента создает список из элементов n, которые выступают ссылкой, ведущей на один и тот же список, поэтому все строки списка являются одной и той же строкой.

Двумерный список нельзя создавать посредством операции повторений одной строки. Как найти выход? Существует несколько решений.

Первое решение: создайте список из n элементов (например, из n нулей). После чего сделайте каждый элемент списка в виде ссылки на другой одномерный список, состоявший из m элементов:

A = [0] * n
for i inrange(n):
A[i] = [0] * m

Второе решение (похожее): для начала создайте пустой список, затем n раз добавьте в него новый элемент, выступающий списком-строкой:

A = []
for i inrange(n):
A.append([0] * m)

Однако проще всего воспользоваться генератором, а именно создать список из n элементов, каждый из которых тоже будет списком из m нулей:

A = [[0] * m for i inrange(n)]

В таком случае каждый элемент будет создаваться независимо от других (для заполнения очередного элемента списка заново конструируется список [0] * m, а не копируются ссылки на один и тот же список.

Ввод двумерного массива

Программа получает двумерный массив на вход представленный n строками, каждая из которых содержит m чисел, которые разделены пробелами. Сосчитать их можно следующим образом:

A = []
for i inrange(n):
A.append(list(map(int, input().split())))

Есть еще один способ – не прибегать к сложных вложенных вызов функций:

A = []
for i inrange(n):
row = input().split()
for i inrange(len(row)):
row[i] = int(row[i])
A.append(row)

Также можно воспользоваться генератором:

A = [list(map(int, input().split())) for i inrange(n)]

Обработка двумерного массива

Перед вам квадратный массив, состоящий из n строк и n столбцов. Элементам на главной диагонали, проходящий от левого верхнего в правый нижний угол(тем элементамA[i][j], для которых ij) необходимо присвоить значение 1, а элементам выше главной диагонали – значение 0, элементам, что ниже главной диагонали – 2. Получиться такой массив (для n=4):

1 0 0 0
2 1 0 0
2 2 1 0
2 2 2 1

Решить такую задачу можно несколькими способами. Элементы, лежащие выше главной диагонали -[i][j], для которых i<диагонали – это элементы A[i][j], для которых i<j, а для элементов ниже главной диагонали i>j. Так, можно сравнить значение i и j и определить значение A[i][j]. Получиться следующий алгоритм:

for i inrange(n):
for j inrange(n):
if i < j:
A[i][j] = 0
elifi > j:
A[i][j] = 2
else:
A[i][j] = 1

Этот алгоритм плохой, так как выполняет 1-2 функции if, чтобы обработать каждый элемент. Если несколько усложнить алгоритм, то можно и вовсе обойтись без условных инструкций. В первую очередь заполните главную диагональ. Здесь потребуется один цикл:

for i inrange(n):
A[i][i] = 1

Далее заполните все элементы главной диагонали значением 0. Для этого в каждой из строй с номером i присвоить значение элементам A[i][j] для j=i+1, …, n-1. Потребуются вложенные циклы:

for i inrange(n):
for j inrange(i + 1, n):
A[i][j] = 0

Точно также присваиваем элементам A[i][j] для j=0, …, i-1 значение 2:

for i inrange(n):
for j inrange(0, i):
A[i][j] = 2

Также можно объединить внешние циклы в один, чтобы получить более компактное решение:

for i inrange(n):
for j inrange(0, i):
A[i][j] = 2
A[i][i] = 1
for j inrange(i + 1, n):
A[i][j] = 0

Еще одно решение, которое подразумевает использование операции повторения списков с целью построения очередной строки списка . i-я строка списка состоит из i чисел 2, а после него одно число 1, затем идет n-i-1 число 0:

for i inrange(n):
A[i] = [2] * i + [1] + [0] * (n — i — 1)

Цикл можно заменить на генератор:

A = [[2] * i + [1] + [0] * (n — i — 1) for i inrange(n)]

Вложенные генераторы двумерных массивов

Вложенные генераторы успешно используются для создания двумерных массивов. Разместите генератор списка, выступающий строкой, внутри генератора для строк. К примеру, сделайте список из n строк и m столбцов посредством генератора, создающего список из n элементов. При этом каждый элемент будет списком из m нулей:

[[0] * m for i inrange(n)]

Внутренний список так можно создать с помощью следующего генератора: [0 for j inrange(m)]. После того как вы вложите один генератор в другой получится вложенные генераторы:

[[0 for j inrange(m)] for i inrange(n)]

Однако если заменить число 0 на некоторое выражение, зависящее от j (номер столбца) и i (номер строки), то получите список, заполненный по некоторой формуле.

Представьте, что нужно задать следующий массив (дополнительные пробелы между элементами были добавлены для удобства):

0 0 0 0 0 0
0 1 2 3 4 5
0 2 4 6 8 10
0 3 6 9 12 15
0 4 8 12 16 20

В текущем массиве m = 6 столбцов, n = 5 строк, и элемент в столбце j и строке i вычисляется по формуле:

A[i][j] = i * j.

Чтобы создать такой массив можно применять генератор:

[[i * j for j inrange(m)] for i inrange(n)]

Оцените статью
Образовательный портал WELCOME4U.RU
Добавить комментарий

Adblock
detector