Python. Контейнеры
Время чтения: 8 минут
Контейнеры это незаменимый инструмент при работе с наборами данных – давай их изучим. Существуют следующие типы контейнеров:
- Списки
- Кортежи
- Словари
Списки
Зачастую, тебе не хватает переменной, чтобы вместить все данные – например, тебе нужно посчитать среднюю оценку для всей группы в университете по какому-то предмету (человек 25, например). Ты мог бы создать переменные “student_1”, “student_2”, “student_3” и так далее, но это была бы очень монотонная и занудная работа.
К счастью разработчики очень ленивые, и давно придумали решение этой проблемы – список (list).
Создание
Создание списка выглядит вот так:
student_marks = [4, 5, 3, 3, 4, 5, 5, 3, 2, 5]
В списке могут содержаться значения любых типов (даже другие списки):
student_marks = [1, '2', 'Three', [3, 11.2]]
student_marks
это переменная – получается, что в переменных могут храниться не только обычные типы (числа и строки), но и списки, и много чего ещё. Это как раз и является проявлением динамической типизации, про которую я говорил во вводной статье. Вот мощная статья, если хочешь глубже понять что такое динамическая типизация.
Также, ты можешь создать список пустым, чтобы потом его наполнить:
student_marks = []
Наполнение
После того, как список создан, в него можно добавлять новые элементы:
student_marks.append(4)
Можно вставлять в произвольное место в массиве (тут используется индекс – про него будет сказано ниже):
# 2 - индекс, куда надо вставить
# 4 - значение
student_marks.insert(2, 4)
# Так можно вставить в начало списка
student_marks.insert(0, 4)
А также можно добавлять в конец все элементы других списков:
another_marks = [2, 3, 5]
student_marks.extend(another_marks)
# Или так
student_marks += another_marks
Вывод значений
Чтобы вывести значения списка, можно просто передать его в print():
student_marks = [2, 3, 4, 5]
print(student_marks)
# Вывод будет такой:
# [2, 3, 4, 5]
Функции для работы со списками
В Python существуют встроенные функции для работы со списками:
- sum(твой-список) – сумма элементов списка
- len(твой-список) – количество элементов списка
- sorted(твой-список) – создать новый список, отсортированный по возрастанию
Вернёмся к задаче поиска средней оценки по группе. Вот так может выглядеть решение:
student_marks = [4, 5, 3, 3, 4, 5, 5, 3, 2, 5]
average_mark = sum(student_marks) / len(student_marks)
print(average_mark)
А что, если мы захотим достать самую высокую оценку, и самую низкую оценку?
Тогда давай сначала мы отсортируем список:
student_marks = [3, 2, 3, 5, 4, 5]
student_marks = sorted(student_marks)
По умолчанию списки сортируются по возрастанию. Если нужно отсортирвать его по убыванию, то надо вызвать эту функцию так:
student_marks = sorted(student_marks, reverse=True)
Мы указали опциональный параметр функции – мы дойдём до этого в статье по функциям.
А теперь надо достать самую низкую оценку из начала списка, и самую высокую оценку из конца списка. Чтобы это сделать, надо понять что такое индексы.
Индексы списка
Индекс – смещение относительно первого элемента.
В то время, как нормальные люди считают порядковый номер элемента (первый, второй, третий…) – программисты считают смещение от первого элемента списка (на ноль, на один, на два).
Получаем значение по индексу
То есть чтобы получить первый элемент списка, нужно взять элемент по индексу 0:
student_marks = [1, 3, 5]
print(student_marks[0]) # 1
print(student_marks[1]) # 3
print(student_marks[2]) # 5
Внимание! Следи чтобы индекс не выходил за пределы списка – это приведёт к ошибке при исполнении программы:
x = [1, 2, 3]
print(x[3])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range
Получаем значение по индексу с конца
А чтобы взять последний элемент, нужно взять элемент по индексу (количество элементов)-1, потому что мы начали считать с 0:
my_list = [3, 5, 7]
print(student_marks[len(student_marks) - 1]) # 7
print(student_marks[len(student_marks) - 2]) # 5
print(student_marks[len(student_marks) - 3]) # 3
Также, если указывать отрицательное значение, то индекс будет считаться с конца:
my_list = [3, 5, 7]
print(student_marks[-1]) # 7
print(student_marks[-2]) # 5
print(student_marks[-3]) # 3
Перезаписываем значение по индексу
Используя индекс, можно перезаписать произвольный элемент списка:
student_mark[1] = 5 # Заменили значение второго элемента на 5
На самом деле индексация в списках устроена несколько иначе – здесь можно почитать немного теории (а потом там идёт реализация на C++).
Слайсы
Ты можешь “разрезать” список на более маленькие списки с помощью слайсов (можно перевести как ломтик, кусочек, отрезанная часть).
Исходный массив:
student_marks = [5, 3, 2, 4, 3, 5]
- При задании слайса, ты указываешь индекс элемента, “от” которого начинается слайс, и индекс элемента, “до” которого нужно сделать слайс
student_marks[0:3] # [5, 3, 2]
- Если индекс “от” не указан, то будет взят слайс от начала списка до индекса “до”
student_marks[:2] # [5, 3]
- Если не указан индекс “до” то будет взят слайс от индекса “от” до последнего элемента списка
student_marks[1:] # [3, 2, 4, 3, 5]
- Если в слайсе не указаны границы, то слайс будет таким же, как список
student_marks[:] # [5, 3, 2, 4, 3, 5]
Задание на закрепление
Создай список со значениями плотности населения (человек на квадратный километр) в 7 самых больших странах мира:
- Россия: 8.56
- Канада: 3.5
- Китай: 139
- США: 32
- Бразилия: 23.6
- Австралия: 2.8
- Индия: 357
Задания:
- Вычисли среднюю плотность населения по этим странам
- Выведи самую низкую плотность
- Выведи самую высокую плотность
- Выведи список из 3 самых больших значений плотности (это про слайсы)
Кортежи
Кортеж (tuple) – это список, который нельзя изменять.
Кортеж более эффективно использует память, поэтому его лучше использовать, когда у тебя есть фиксированный набор значений (например кортеж, в котором перечислены планеты Солнечной системы или дни недели).
Пример создания кортежа:
days_of_week = ('Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота', 'Воскресенье')
В кортеже также могут содержаться значения любых типов:
some_tuple = ('1', 2, [3, 4], 5.5)
Значения кортежа можно доставать через индекс, но перезаписывать их нельзя:
x = (1, 2, 3)
print(x[1]) # 2
x[1] = -2 # ОШИБКА
Так как ты не можешь изменять кортеж, функции добавления элемента в конец (append) и добавления списка в конец (extend) использовать нельзя – в остальном поведение такое же как и у списков (индексы, слайсы и функции для работы со списками).
Словари
Словарь (dict) – это список, в котором хранятся пары ключ-значение. Ключ при этом должен быть уникальным и неизменяемым.
На самом деле словари в Python это хэш-таблицы – в них ОЧЕНЬ быстро происходит поиск значений. Вот про них на русском (там мало информации) и на английском (отличная статья).
Создание
Словарь создаётся так:
students = {
'Иванов Иван Иванович': 4,
'Сергеев Сергей Сергеевич': 3,
'Максимов Максим Максимович': 5,
}
Также ключом может быть число (например уникальный ID пользователя), а значением вообще список:
ids = {
102: [2, 3, 4],
103: [3],
105: [5, 4],
}
Благодаря свойству неизменности, кортежи тоже могут быть ключами, наравне с числами и строками. Например:
numbers = {
('One', 1) : 'Un',
('Two', 2) : 'Deux',
('Three', 3) : 'Trois'
}
Или другой словарь:
# Ключ - имя, значение - словарь {ключ - предмет, значение - оценка}
students = {
'Иванов Иван Иванович': {
'Основы Python': 4,
'Философия': 4,
},
'Сергеев Сергей Сергеевич': {
'Основы Python': 3,
'Философия': 5,
},
'Максимов Максим Максимович': {
'Основы Python': 5,
'Философия': 3,
},
}
Также в словаре могут быть значения разных типов (это редко пригождается):
some_dict = {
1: '1',
'1': 1,
(3, '1'): [3, 1, '1']
}
Как можно заметить, словари уже позволяют описывать довольно сложные наборы данных, в отличии от всего, что мы ранее рассматривали.
Вывод значений
Чтобы вывести значения словаря, можно просто передать его в print():
students = {
'Иванов Иван Иванович': {
'Основы Python': 4,
'Философия': 4,
}
}
print(students)
# Вывод будет такой:
# {'Иванов Иван Иванович': {'Основы Python': 4, 'Философия': 4}}
Получение значения по ключу
Так как ключ в словаре является уникальным, мы всегда можем получить из словаря нужное значение, зная ключ. Получение значения по ключу выглядит так же, как получение значения из списка по индексу – лишь с той разнцей, что мы передаём ключ:
print(students['Иванов Иван Иванович'])
# Выведет:
# {'Основы Python': 4, 'Философия': 4}
Добавление значения в словарь
Чтобы добавить в словарь новое значение, необходимо указать нужный ключ:
# Записываем оценки по предметам для студента
students['Семёнов Семён Семёнович'] = {'Основы Python': 3, 'Философия': 3}
Если ты укажешь уже существующий в словаре ключ, то ты перезапишешь старое значение по этому ключу.
Функции для работы со словарями
Ты можешь использовать следующие функции, для работы со словарями:
- len(твой-список) – количество элементов словаря
- list(твой-список.keys()) – получить список ключей словаря
- list(твой-список.values()) – получить список значений словаря
- list(твой-список.items()) – получить список пар ключ-значение словаря
Получение списка ключей, значений и пар ключ-значение обёрнуто в list() из-за того, что функции возвращают не “чистые” списки, а нечто другое. Пока что давай опустим что это такое, и просто используем функции как я написал.
Вот примеры использования:
students = {
'Иванов Иван Иванович': 4,
'Сергеев Сергей Сергеевич': 3,
'Максимов Максим Максимович': 5,
}
len(students) # 3
list(students.keys()) # ['Иванов Иван Иванович', 'Сергеев Сергей Сергеевич', 'Максимов Максим Максимович']
list(students.values()) # [4, 3, 5]
# Обрати внимание, что каждая пара ключ-значение это кортеж из двух элементов -- ключа и значения.
list(students.items()) # [('Иванов Иван Иванович', 4), ('Сергеев Сергей Сергеевич', 3), ('Максимов Максим Максимович', 5)]
Задание на закрепление
Создай словарь, где ключом является название планеты, а значением дистанция до Солнца в километрах:
- Меркурий: 57910006
- Венера: 108199995
- Земля: 149599951
- Марс: 227939920
- Юпитер: 778330257
- Сатурн: 1429400028
- Уран: 2870989228
- Нептун: 4504299579
Задания:
- Вычисли среднее расстояние до Солнца, учитывая все планеты
- Выведи отсортированный список названий всех планет (функция sorted() умеет сортировать не только числа)
- Вычисли во сколько раз Нептун дальше от Солнца, чем Земля
Заключение
Итого, мы изучили:
- Контейнеры
- Списки (создание, наполнение, функции для работы, индексы, слайсы)
- Кортежи
- Словари (ключ-значение, перезаписывание при наполнении)
Гигантский объём новой информации, да? Но ничего, ты делаешь офигенные успехи!
Если что – пиши, я помогу и постараюсь объяснить лучше.
Дальше мы рассмотрим основу логики в программировании – условия.