Материалы, подготовленные в результате оказания услуги, помогают разобраться в теме и собрать нужную информацию, но не заменяют готовое решение.

Матрицы в Python: создание вложенных списков и использование вложенных генераторов

Статью подготовили специалисты образовательного сервиса Zaochnik.

Содержание:

Понятие и создание матриц

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

Пример 1

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

```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`.

Для вывода и обработки такого списка обычно происходит с помощью двух вложенных циклов. Где первый проходит по строкам, а второй — по элементам внутри каждой строки.

Пример 2

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

```python

for i in range(len(A)):

     for j in range(len(A[i])):

          print(A[i][j], end=' ')

     print()

```

Есть и альтернативный подход — использовать циклы по элементам списка, а не по индексам:

Пример 3

```python

for row in A:

     for elem in row:

          print(elem, end=' ')

     print()

```

Для удобного вывода одной строки с использованием метода `join`, можно применить следующий код:

Пример 4

```python

for row in A:

     print(' '.join(map(str, row)))

```

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

Пример 5

```python

Sum = 0

for i in range(len(A)):

     for j in range(len(A[i])):

          Sum += A[i][j]

```

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

Пример 6

```python

Sum = 0

for row in A:

     for elem in row:

          Sum += elem

```

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

Предположим, у вас есть два значения `n` и `m`, где:

  • `n` - количество строк
  • `m` - количество столбцов.

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

Пример 7

```python

! Неправильно

A = [[0] * m] * n

```

Тем не менее, если вы установите значение `A[0][0]` равным `1`, и затем выведете `A[1][0]`, то получите также `1`. Это происходит, поскольку ` [0] * m` создает ссылку на один и тот же список из `m` нулей. Повторяя этот элемент, мы создаем массив из `n` компонентов, которые указывают на один и тот же список.

Поэтому двумерный список нельзя корректно создать с помощью операции повторения одной строки.

Первый способ решения - сначала создаем список из `n` элементов, который изначально состоит из нулей, а затем присваиваем каждому элементу ссылку на одномерный список из `m` элементов:

Пример 8

```python

A = [0] * n

for i in range(n):

     A[i] = [0] * m

```

Альтернативный метод — создать пустой список и добавлять в него новый элемент, представляющий собой строку, `n` раз:

Пример 9

```python

A = []

for i in range(n):

     A.append([0] * m)

```

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

Пример 10

```python

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

```

При таком способе каждый элемент формируется отдельно, что исключает копирование ссылок на один и тот же список.

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

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

Пример 11

```python

A = []

for i in range(n):

     A.append(list(map(int, input().split())))

```

Либо, чтобы избежать сложных вложенных вызовов, можно сделать так:

Пример 12

```python

A = []

for i in range(n):

     row = input().split()

     for j in range(len(row)):

          row[j] = int(row[j])

     A.append(row)

```

Допустимо воспользоваться генератором для выполнения данной задачи:

Пример 13

```python

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

```

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

Представим, что у нас есть квадратный массив размером `n×n`. Необходимо тем элементам, которые расположены

  • на главной диагонали (от верхнего левого к нижнему правому углу), присвоить значение `1`;
  • элементам выше диагонали — `0`;
  • а элементам ниже — `2`.

Это приведет к следующему массиву (пример в случае `n = 4`):

```

1 0 0 0

2 1 0 0

2 2 1 0

2 2 2 1

```

Можем рассмотреть некоторые из вариантов решения для этой задачи. Элементы, расположенные выше главной диагонали соответствуют условию `A[i][j]`, где `i < j`, а элементы ниже — где `i > j`. Мы можем сравнивать индексы `i` и `j`, чтобы определить, какое значение следует присвоить `A[i][j]`:

```python

for i in range(n):

     for j in range(n):

          if i < j:

               A[i][j] = 0

          elif i > j:

               A[i][j] = 2

         else:

               A[i][j] = 1

```

Тем не менее такой алгоритм не слишком эффективен, так как он требует выполнения одной или двух проверок `if` для каждого элемента. Упрощая алгоритм, можем сразу заполнить главную диагональ одним циклом:

```python

for i in range(n):

     A[i][i] = 1

```

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

```python

for i in range(n):

     for j in range(i + 1, n):

          A[i][j] = 0

```

Подобным образом присвоим значение `2` элементам `A[i][j]` для `j` в диапазоне `0` до `i-1`:

```python

for i in range(n):

     for j in range(0, i):

          A[i][j] = 2

```

Лучше всего объединить внешние циклы в один, с целью получить более компактное решение:

```python

for i in range(n):

     for j in range(0, i):

          A[i][j] = 2

     A[i][i] = 1

     for j in range(i + 1, n):

          A[i][j] = 0

```

Также можно воспользоваться операцией повторения списков для формирования каждой строки. `i`-я строка будет содержать `i` элементов равных `2`, за которыми последует одно число `1` и `n-i-1` нулей:

```python

for i in range(n):

     A[i] = [2] * i + [1] + [0] * (n - i - 1)

```

Или заменив цикл на генератор:

```python

A = [[2] * i + [1] + [0] * (n - i - 1) for i in range(n)]

```

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

Создавая двумерные массивы, также можно применять вложенные генераторы.

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

Пример 14

```python

[[0] * m for i in range(n)]

```

А вот создание внутреннего списка можно произвести с помощью генератора, например: `[0 for j in range(m)]`. Объединив два генератора, мы получаем вложенные генераторы:

Пример 15

```python

[[0 for j in range(m)] for i in range(n)]

```

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

Рассмотрим пример создания следующего массива, где между значениями добавлены пробелы для удобства отображения:

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

В таком примере имеется `n = 5` строк и `m = 6` столбцов, а значение элемента в строке `i` и столбце `j` подсчитывается используя формулу: `A[i][j] = i * j`.

Чтобы создать подобный массив можно использовать следующий генератор:

Пример 16

```python

[[i * j for j in range(m)] for i in range(n)]

```

Этот код эффективно создает двумерный массив, заполняя его значениями согласно заданной формуле.

Навигация по статьям

Выполненные работы по программированию

  • Программирование

    НИР на тему Автоматизированое рабочее места специалиста по социальной работе

    • Вид работы:

      Отчёт по практике

    • Выполнена:

      25 февраля 2020

    • Стоимость:

      1 900 руб.

    Заказать такую же работу
  • Программирование

    Обеспечение защиты информации при использовании системы электронного документооборота

    • Вид работы:

      Реферат

    • Выполнена:

      29 декабря 2019

    • Стоимость:

      500 руб.

    Заказать такую же работу
  • Программирование

    Искусственный интеллект. Достижения и перспективы развития.

    • Вид работы:

      Эссе

    • Выполнена:

      11 декабря 2019

    • Стоимость:

      800 руб.

    Заказать такую же работу
  • Программирование

    Айти. Заполнить дневник практики.

    • Вид работы:

      Отчёт по практике

    • Выполнена:

      9 декабря 2019

    • Стоимость:

      1 800 руб.

    Заказать такую же работу
  • Программирование

    Если свободное общество не сможет помочь многим бедным, оно не сможет защитить немногих богатых

    • Вид работы:

      Эссе

    • Выполнена:

      8 декабря 2019

    • Стоимость:

      1 000 руб.

    Заказать такую же работу
  • Программирование

    Двоичные деревья поиска, Организация поиска в массиве данных при помощи специальных методов поиска, Сортировка

    • Вид работы:

      Отчёт по практике

    • Выполнена:

      28 октября 2019

    • Стоимость:

      1 700 руб.

    Заказать такую же работу