Умскул учебник стремится стать лучше! Если вы наткнулись на ошибку или неточность в нашем материале - просто сообщите нам, мы будем благодарны!
Информатика

Практика работы с массивами

3.5.2022
1596

На этой странице вы узнаете

  • Защита от вторжения: чем полезен тип tuple?
  • Основные метаморфозы массивов: что во что может превращаться?
  • Война с клонами: как нам может помочь тип set?

Вы — величайший придворный маг цифрового королевства.

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

Король повелел вам собрать по замку все зелья, которые неблагодарные, невежественные и необразованные рыцари хватают как попало и бросают, где захочется. Воля короля есть воля короля, надо исполнять.

Команды для работы

Основы теории этого вида магии мы уже знаем — виды массивов, а также работу списков мы рассмотрели в статье «Работа с массивами в Python»

Сейчас кратко вспомним, что:

  • Массив — это структура, которая содержит в себе набор других значений. Массив позволяет хранить упорядоченный набор элементов, каждое значение которого относится к одному и тому же типу данных
  • Список (list) — самый простой вид массива. Он может работать с любыми типами данных — от целых чисел до строк, его можно легко изменять, сортировать и индексировать. Списки могут также хранить в себе другие списки.

Помимо списков, существуют также кортежи, множества и словари. Но как работать с ними, как они устроены и какие для них есть команды?

1. Кортеж (tuple) практически то же самое, что и список — элементы могут принимать любые типы данных, индексируются числами, начиная с 0. Важное отличие — кортеж нельзя изменить. Ни добавить к нему элемент, ни удалить или изменить существующий не получится. 

Создается кортеж либо прописыванием значений в круглых скобках, либо командой tuple.

a = [1, 2, 3, 4]
a = tuple(a)
print(a[2])
a = (1, 2, 3, 4)
print(a[2])

Вывод в обоих случаях будет одинаковый: 3.

Защита от вторжения: чем полезен тип tuple?

В устойчивости и состоит его цель — он должен защитить содержимое от изменений. Если к нему применить команду append (добавить элемент в конец кортежа) или попробовать изменить одно из записанных значений, мы получим ошибку. Но к нему все еще применимы поисковые команды, например, len или count, которые на содержимое никак не повлияют.

2. Множество (set). В чем его особенности?

  • Оно не индексируется — то есть достать элементы по индексу не получится. Наличие элемента во множестве можно проверить с помощью оператора in, а перебрать их — напрямую по элементам, а не по индексам — с помощью цикла for.
  • Автоматически защищает самого себя от повторяющихся значений.
  • Его элементы автоматически отсортированы по возрастанию.

Создается командой set или прописыванием значений внутри фигурных скобок.

a = (1, 2, 3, 2, 1)
s = set(a)
s = {1, 2, 3, 2, 1}

Из полезных функций для работы с множествами:

  • <множество>.add(<элемент>) — добавляет элемент во множество;
  • <множество>.remove(<элемент>) — удаляет элемент из множества.

s = {1, 2, 3, 2, 1}


s.remove(1)
s.add(4)
print(s)


Вывод: {2, 3, 4}


3. Словарь (dict). Работает буквально как словарь, например, русского языка. Вместо индексов мы можем задать любые так называемые ключи. Каждому из них будет соответствовать другое значение, которое можно найти только по его ключу.

Значения для всех ключей можно изменять напрямую, как и добавлять — просто указывая нужный ключ. 

Пустой словарь создается командой dict или фигурными скобками, в которых данные прописаны в виде <ключ>: <значение>.

Из полезных функций:

  • <словарь>[<key>] — получаем элемент с заданным ключом.

d = {1: “один”, “key”: “value”, 111:222}
print(d[“key”])


Вывод: “value”


  • Также мы можем добавлять значения в словарь. Для этого нам нужно указать значение и ключ, который будет вести к этому значению. <словарь>[<key>] = <значение>.

d = dict()
d[111] = 333
d[4] = “сами добавили”
print(d)


Вывод: {111: 333, 4: “сами добавили”}


Основные метаморфозы массивов: что во что может превращаться?

Важно запомнить: типы массивов list (список), tuple (кортеж) и set (множество) можно превращать один в другой. Например, мы можем преобразовать список A в кортеж командой tuple(A). 

Но словарь нельзя преобразовать в какой бы то ни было другой массив, как и наоборот — к словарю другие массивы нельзя привести.

Практика создания и преобразования массивов

Разобравшись с тем, на что способна наша магия, мы можем ее применить и, наконец, выполнить волю нашего короля — прибраться за рыцарями.

Наша задача:

  1. Походить по замку и просто сложить в сумку все зелья, что найдем.
  2. Создать подробный отчет о наличии зелий и их количестве.
  3. По особому заказу короля сделать новое зелье.
  4. Также по просьбе короля выделить в королевский музей по одному зелью каждого вида.

Шаг 1. Для выполнения первой задачи — сбора зелий в мешок — удобно использовать список. За счет его гибкости в любой момент мы можем как добавить зелье в мешок, так и убрать его оттуда.

И вот, прогулявшись по замку, в наш список-мешок мы собрали следующие зелья:


bag = [«Зелье лечения», «Зелье невидимости», «Вода», «Зелье лечения»,
    «Зелье огня», «Зелье магии», «Зелье силы», «Зелье магии»
    «Зелье силы», «Зелье магии», «Зелье выносливости»,
    «Зелье лечения», «Зелье защиты», «Зелье огня»,
    «Зелье защиты», «Зелье огня», «Зелье магии», «Зелье холода»,
    «Зелье защиты», «Зелье огня», «Зелье невидимости», «Зелье холода»,
    «Зелье выносливости»]
potion_on_floor = «Зелье лечения»


Выглядит некрасиво, но мы же будем все это прямо по пути сортировать и документировать… Стоп. Откуда в нашем мешке простая вода? И почему на полу все еще валяется какое-то зелье?

Непорядок. Воду мы, наверно, случайно подобрали. Ее из списка надо удалить, а зелье с пола — подобрать и добавить.


    bag.remove(«Вода»)
bag.append(potion_on_floor)


Шаг 2. Теперь, когда все необходимое в мешок добавлено, а ненужное — убрано, мы готовы приступать ко второму шагу нашего плана — составлению отчета.

Война с клонами: как нам может помочь тип set?

Как создать список-отчет о том, какие зелья у нас есть и исключить повторы?

1. Долго и упорно перебирать мешок, пока в нем не останется одинаковых элементов, чтобы нам не попадались в списке одинаковые зелья.

2. Вспомнить, что множество само по себе исключает повторы внутри себя, и просто создать его.

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


set_of_potions = set(bag)


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

Но простого списка зелий мало, нам необходимо знать и их количество. Что мы можем для этого использовать?

  • словарь — где для каждого зелья будет указано его количество;
  • цикл for — чтобы перебирать зелья по списку;
  • функция count — чтобы считать количество каждого зелья в мешке.

count_of_potions = dict()
for potion in set_of_potions:
      count_of_potions[potion] = bag.count(potion)


Перебирая зелья potion по нашему уникальному списку зелий set_of_potions, для каждого нового potion в словаре count_of_potions мы создадим новый элемент. Ключом элемента будет само зелье, а значением — его количество из мешка.

Шаг 3. Нам еще нужно создать особое зелье по заказу короля, причем в двух экземплярах. Оно так и называется — Особое зелье. Получить его можно, если смешать зелья лечения, огня и магии.

Для этого нам необходимо:

  1. Вынуть эти зелья из мешка.
  2. Учесть расход зелий в count_of_potions.
  3. Когда создадим новое зелье, добавляем его в наш список зелий, а также в общий мешок и в учет количества зелий (не забывая, что у нас их два).

for i in range(2):
            bag.remove(«Зелье лечения»)
            bag.remove(«Зелье огня»)
            bag.remove(«Зелье магии»)

count_of_potions[«Зелье лечения»] -= 2
count_of_potions[«Зелье огня»] -= 2
count_of_potions[«Зелье магии»] -= 2

bag.append(«Особое зелье»)
bag.append(«Особое зелье»)

set_of_potions.add(«Особое зелье»)

count_of_potions[«Особое зелье»] = 2


Шаг 4. Наша следующая задачавыделить в музей по 1 экземпляру каждого зелья.

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

for_museum = []
for potion in set_of_potions:
            count_of_potions[potion] -= 1
            for_museum.append(potion)
for_museum = tuple(for_museum)


Теперь на наши музейные экспонаты буквально можно только смотреть, забрать их никто не сможет.

После всех действий давайте посмотрим на результат нашей работы. Для наглядности будем выводить значения последовательно, чтобы видеть прогресс изменений. Пустой print нужен, чтобы создавать пустые строки, так вывод будет читаться легче.


bag = [«Зелье лечения», «Зелье невидимости», «Вода», «Зелье лечения»,
                        «Зелье огня», «Зелье магии», «Зелье силы», «Зелье магии»,
                        «Зелье силы», «Зелье магии», «Зелье выносливости»,
                        «Зелье лечения», «Зелье защиты», «Зелье огня»,
                        «Зелье защиты», «Зелье огня», «Зелье магии», «Зелье холода»,
                        «Зелье защиты», «Зелье огня», «Зелье невидимости», «Зелье холода»,
                        «Зелье выносливости»]
potion_on_floor = «Зелье лечения»

bag.remove(«Вода»)
bag.append(potion_on_floor)

set_of_potions = set(bag)
print(«Вот список различных зелий, которые мы собрали:», set_of_potions)
print()

count_of_potions = dict()
for potion in set_of_potions:
count_of_potions[potion] = bag.count(potion)
print(«Вот учет зелий по количеству:», count_of_potions)
print()

for i in range(2):
            bag.remove(«Зелье лечения»)
            bag.remove(«Зелье огня»)
            bag.remove(«Зелье магии»)

count_of_potions[«Зелье лечения»] -= 2
count_of_potions[«Зелье огня»] -= 2
count_of_potions[«Зелье магии»] -= 2

bag.append(«Особое зелье»)
bag.append(«Особое зелье»)

set_of_potions.add(«Особое зелье»)

count_of_potions[«Особое зелье»] = 2
print(«Вот учет зелий после создания нового:», count_of_potions)
print()

for_museum = []
for potion in set_of_potions:
            bag.remove(potion)
            count_of_potions[potion] -= 1
            for_museum.append(potion)
for_museum = tuple(for_museum)
print(«В музей отправляются:», for_museum)
print(«Вот учет зелий после отправки части в музей:», count_of_potions)
print()


Вывод:
Вот список различных зелий, которые мы собрали: {‘Зелье холода’, ‘Зелье магии’, ‘Зелье лечения’, ‘Зелье силы’, ‘Зелье выносливости’, ‘Зелье невидимости’, ‘Зелье огня’, ‘Зелье защиты’}

Вот учет зелий по количеству: {‘Зелье холода’: 2, ‘Зелье магии’: 4, ‘Зелье лечения’: 4, ‘Зелье силы’: 2, ‘Зелье выносливости’: 2, ‘Зелье невидимости’: 2, ‘Зелье огня’: 4, ‘Зелье защиты’: 3}

Вот учет зелий после создания нового: {‘Зелье холода’: 2, ‘Зелье магии’: 2, ‘Зелье лечения’: 2, ‘Зелье силы’: 2, ‘Зелье выносливости’: 2, ‘Зелье невидимости’: 2, ‘Зелье огня’: 2, ‘Зелье защиты’: 3, ‘Особое зелье’: 2}

В музей отправляются: (‘Зелье холода’, ‘Зелье магии’, ‘Зелье лечения’, ‘Зелье силы’, ‘Зелье выносливости’, ‘Зелье невидимости’, ‘Особое зелье’, ‘Зелье огня’, ‘Зелье защиты’)
Вот учет зелий после отправки части в музей: {‘Зелье холода’: 1, ‘Зелье магии’: 1, ‘Зелье лечения’: 1, ‘Зелье силы’: 1, ‘Зелье выносливости’: 1, ‘Зелье невидимости’: 1, ‘Зелье огня’: 1, ‘Зелье защиты’: 2, ‘Особое зелье’: 1}


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

Практика для подготовки к экзамену

Массивы в ЕГЭ по информатике встречаются повсеместно. Например, это могут быть задания 17, 25, 26, 27, но массивы могут быть полезны и при решении других номеров. 

Разберем один из вариантов задания 17 ЕГЭ по информатике.

В файле содержится последовательность целых чисел из диапазона [-10000, 10000]. Определите количество пар элементов, в которых сумма модулей элементов больше 700, а также максимальное из чисел, которое может являться элементом таких пар. В качестве пары рассматривается два элемента, идущие друг за другом. В ответ запишите целые числа через пробел: сначала количество, затем максимальное значение.
Файл:
2.txt

Пример:
4
1284
450
4
-90

Ответ для примера: 2 1284

Решение.

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

1) Первым делом откроем файл:

f = open(«2.txt»)

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

2) Далее создадим два списка, в первом будут храниться все числа из файла, а во втором все числа, подходящие под условия задачи:

a = []
b = []

3) Считаем данные в список с помощью цикла. При такой конструкции цикла for переменная s будет поочередно принимать значение каждой строки из файла до тех пор, пока эти строки в нем не закончатся:

for s in f:

4) В список добавляем число с помощью метода append() — он добавит в конец списка то, что ему будет передано в скобках. При добавлении нам потребуется приводить значение к целочисленному типу, для этого используем функцию int():

     a.append(int(s))

5) Создадим переменную-счетчик, так как нам нужно найти количество подходящих пар элементов:

count = 0

6) С помощью цикла for пройдемся по всем элементам списка, чтобы рассматривать все элементы попарно. Важным моментом является правильное прохождение списка.Так как мы проверяем числа парами (индексы: i, i+1), то нам необходимо в счетчике индексов из длины списка вычесть единицу, чтобы не выйти за границу и не поймать ошибку выхода за пределы списка из-за элемента с индексом i+1 в самом конце.

for i in range(len(a)-1):

7) В условии записываем все то, что требует от нас задача:

 if (abs(a[i]) + abs(a[i+1])) > 700:

8) Осталось при истинности условия увеличивать счетчик на единицу:

 count += 1

9) Далее с помощью команд b.append(a[i]) и b.append(a[i + 1]) добавим в список b все числа, подходящие под наше условие, для того, чтобы в дальнейшем найти максимальное число из них. Методы, применяемые для работы со списками, мы разбирали в статье «Работа с массивами в Python».

b.append(a[i])
b.append(a[i + 1])

10) В конце выводим количество таких пар и максимальное число с помощью max(b):

print(count, max(b))

Полный код программы:

f = open(«2.txt»)
a = []
b = []
for s in f:
    a.append(int(s))
count = 0
for i in range(len(a)-1):
    if (abs(a[i]) + abs(a[i+1])) > 700:
        count += 1
        b.append(a[i])
        b.append(a[i + 1])
print(count, max(b))

В результате должен получиться ответ: 4488 9999

Вот и подошла к концу наша «магическая» статья. Мы освоили такие понятия, как кортеж, множество, список и словарь, посмотрели их применение на практике и в задачах ЕГЭ. Желающих узнать о дополнительных возможностях программирования на Python мы приглашаем в статью «Функции и рекурсия».

Термины

len() — это функция, которая считает длину (количество элементов) в объекте.  

count() — это функция, которая подсчитывает количество заданных элементов в объекте.

Индексация — это доступ к отдельным элементам чего-либо (строки, массива и т.п.) по порядковому номеру этого элемента (его индексу). В Python индексация начинается с 0.

Модуль числа — это абсолютная величина этого числа, его неотрицательное значение. Говоря упрощенно, при взятии модуля нужно отбросить от числа его знак + или -. 

Типы данных — виды значений, которые может принимать переменная. Подробнее о разных типах данных можно узнать в статье «Основы программирования на языке Python. Часть 1».

Цикл for это цикл, который используется для выполнения команды или набора команд определенное количество раз или для перебора набора данных.

Фактчек

  • Кортеж — это практически то же самое, что и список, но с одним исключением: его значения нельзя изменять.
  • Множество позволяет сохранять уникальность своих элементов, но оно не индексируется.
  • Словарь хранит данные в виде <ключ: значение>, где у каждого ключа есть свое значение.

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

Проверь себя

Задание 1.
Без запуска кода определите, что выведет следующий код.


a = (1, 2, 3, 4, 5)
b = a[3]
print(b)


  1. 3
  2. 4
  3. 2
  4. Ошибку

Задание 2.
Без запуска кода определите, что выведет следующий код.


a = {1, 2, 3, 4, 5}
b = a[3]
print(b)


  1. 3
  2. 4
  3. 2
  4. Ошибку

Задание 3.

Без запуска кода определите, что выведет следующий код.


a = {1:2, 5:6, 3:4}
b = a[3]
print(b)


  1. 4
  2. 5
  3. 6
  4. Ошибку

Ответы: 1. — 2; 2. 4; 3. — 1.

Понравилась статья? Оцени:
Читайте также:

Читать статьи — хорошо, а готовиться к экзаменам
в самой крупной онлайн-школе — еще эффективнее.

50 000
Количество
учеников
1510
Количество
стобальников
>15000
Сдали на 90+
баллов