Структура данных — это способ организации данных в компьютере, позволяющий прогерам эффективно и удобно их использовать. Структур данных существует достаточно много, и мы с Вами познакомимся с большинством из них — но пока будем двигаться с по порядку.
Список — это абстрактный тип данных, хранящий в себе упорядоченный набор значений. Обозначается через квадратные скобки [].
Способы инициализации
Список можно создавать разными способами — от прямого задания в исходном коде до использования функции list() или ввода данных с клавиатуры.
1. Пустой список
arr = []
2. Список с начальными значениями
arr = [1, 2, 3, 4]
3. Список с повторяющимися значениями
arr = [0] * 5 # [0, 0, 0, 0, 0]
arr = [""] * 3 # ["", "", ""]
4. Через генератор списков
arr = [i for i in range(5)] # [0, 1, 2, 3, 4]
arr = [i**2 for i in range(3)] # [0, 1, 4]
5. Через функцию list()
arr = list() # пустой список
arr = list("abc") # ['a', 'b', 'c']
arr = list((1, 2, 3)) # [1, 2, 3]
6. С клавиатуры
arr = []
n = int(input("Введите размерность массива: "))
for i in range(n):
elem = int(input(f"Введите {i + 1} элемент : "))
arr.append(elem)
Взаимодействие
Поскольку список является изменяемым типом данных, с ним можно выполнять множество операций: заменять элементы, добавлять и удалять их по индексу, вычислять длину, а также извлекать отдельные срезы. Не забываем про то, что индексация у нас начинается с 0. Разберем на примере: пускай у нас есть массив наших тачек arr = ['Ауди', 'Мерседес', 'БВМ', 'Хонда']
1. Доступ через индексы
Мы можем обращаться к конкретному элементу по его индексу. Если мы хотим взять несколько элементов, то используем срез [x:y:z]
, где x - индекс, с которого мы начинаем, y - индекс, перед которым мы останавливаемся и z - индекс, который обозначает наш шаг.
arr = ['Ауди', 'Мерседес', 'БВМ', 'Хонда']
x = arr[0] # первый элемент, то есть 'Ауди'
y = arr[-1] # последний, то есть 'Хонда'
sub_1 = arr[:2] # начинаем с 0 индекса и идем до индекса 2
print(sub_1) # ['Ауди', 'Мерседес']
sub_2 = arr[1:2] # начинаем с индекса 1 и идем до индекса 2
print(sub_2) # ['Мерседес']
sub_3 = arr[:3:2] # начинаем с индекса 0 и идем до индекса 3 с шагом 2
print(sub_3) # ['Ауди', 'БВМ']
sub_4 = arr[3::-2] # начинаем с индекса 3 и идем до индекса 0 с шагом -2
print(sub_4) # ['Хонда', 'Мерседес']
Отрицательный шаг работает только тогда, когда в нашем срезе x > y.
2. Изменение содержимого
В процессе работы со списком, мы также можем изменять его элементы.
arr = ['Ауди', 'Мерседес', 'БМВ', 'Хонда']
arr.append('Порше') # Добавляет элемент в конец списка
print(arr) # ['Ауди', 'Мерседес', 'БМВ', 'Хонда', 'Порше']
l = ['Форд', 'Ламба']
arr.extend(l) # Расширяет список, добавляя в конец все элементы списка l
print(arr) # ['Ауди', 'Мерседес', 'БМВ', 'Хонда', 'Порше', 'Форд', 'Ламба']
arr.insert(1, 'Форд') # Вставляет на 1-й элемент значение Форд
print(arr) # ['Ауди', 'Форд', 'Мерседес', 'БМВ', 'Хонда', 'Порше', 'Форд', 'Ламба']
arr.pop(1) # Удаляет 1-й элемент. Если индекс не указан, то удаляется последний элемент
print(arr) # ['Ауди', 'Мерседес', 'БМВ', 'Хонда', 'Порше', 'Форд', 'Ламба']
ind = arr.index('БМВ', 1, 4) # Возвращает положение первого элемента со значением БМВ, при этом поиск ведется от 1 до 4
print(ind) # 2
k = arr.count('Ауди') # Возвращает количество элементов со значением x
print(k) # 1
arr.reverse() # Разворачивает список
print(arr) # ['Ламба', 'Форд', 'Порше', 'Хонда', 'БМВ', 'Мерседес', 'Ауди']
arr.clear() # Очищает список
print(arr) # []
3. Длина списка
Функция len()
возвращает количество элементов в списке.
arr = ['Ауди', 'Мерседес', 'БМВ', 'Хонда']
print(len(arr)) # 4
4. Циклы
Когда нужно получить значение элемента списка, либо его индекс, мы используем
range()
— перебор с индексами.
arr = ['Ауди', 'Мерседес', 'БМВ', 'Хонда']
# Выводим элементы списка, через индексы
for i in range(len(arr)):
print(arr[i])
# Выводим элементы списка напрямую
for i in arr:
print(i)
# Выводим индексы всех элементов
for i in range(len(arr)):
print(i)
Когда нужно одновременно получить и индекс, и значение элемента в списке, мы используем
enumerate()
— перебор значений.
arr = ['Ауди', 'Мерседес', 'БМВ', 'Хонда']
# Выводим одновременно индексы и элементы
for ind, elem in enumerate(arr):
print(ind, elem)
Несмотря на обилие различных функций, в Python есть ещё некоторые, которые требуют особого внимания.
Метод copy()
— создание копии списка. В Python списки — это изменяемые объекты. Если мы просто присвоим список другой переменной, то у нас не получится создать новый список, мы получим новую ссылку на тот же самый объект в памяти.
arr = ['Ауди', 'Мерседес', 'БВМ', 'Хонда']
arr_copy = arr
arr_copy.append('Лада')
print(arr) # ['Ауди', 'Мерседес', 'БВМ', 'Хонда', 'Лада'] - Хьюстон, у нас проблема
Чтобы избежать этой проблемы, мы используем метод copy()
arr = ['Ауди', 'Мерседес', 'БВМ', 'Хонда']
arr_copy = arr.copy()
arr_copy.append('Лада')
print(arr) # ['Ауди', 'Мерседес', 'БВМ', 'Хонда']
print(arr_copy) # ['Ауди', 'Мерседес', 'БВМ', 'Хонда', 'Лада']
Метод .sort()
— изменение исходного списка, сортируя его элементы в порядке возрастания (по умолчанию). Так как этот метод работает "на месте", то он ничего не возвращает.
arr = ['Ауди', 'Мерседес', 'БМВ', 'Хонда']
arr_sor = arr.sort() # Значение None, так как работаем на месте
print(arr_sor) # None
arr.sort() # Отсортировали список (по возрастанию)
print(arr) # ['Ауди', 'БМВ', 'Мерседес', 'Хонда']
Метод
.sort()
сортирует строки по алфавиту, точнее — лексикографически, сравнивая коды символов в используемой кодировке, обычно это Unicode (A
имеет код 1040, аБ
имеет код 1041). Сравнение начинается с первых символов. Если они одинаковые, то переходим ко второму и так далее.
Кроме того, данный метод имеет несколько параметров. Если требуется отсортировать список, например, по длине слова или по убыванию, можно использовать следующие штуки.
arr = ['Ауди', 'Мерседес', 'БМВ', 'Хонда']
arr.sort(reverse=True) # Сортировка по убыванию
print(arr) # ['Хонда', 'Мерседес', 'БМВ', 'Ауди']
arr.sort(key=len) # Сортировка по длине строки
print(arr) # ['БМВ', 'Ауди', 'Хонда', 'Мерседес']
Кортеж — это упорядоченный, неизменяемый набор элементов, который может содержать элементы разных типов. Кортежи обозначаются круглыми скобками ().
Они похожи на списки, но с одним ключевым отличием: после создания их нельзя изменить. Это делает их идеальными для хранения данных, которые не должны меняться в процессе выполнения программы — например, координаты точки, пароли, настройки и т.д.
Способы инициализации
1. Пустой кортеж
tpl = ()
# или так
tpl = tuple()
2. Кортеж с одним элементом
tpl = (5,) # Это кортеж
tpl = (5) # Это просто число в скобках
3. Кортеж с несколькими элементами
tpl = (1, 2, 3)
colors = ('красный', 'зелёный', 'синий')
mixed = (1, 'текст', True, [1, 2, 3]) # может содержать изменяемые объекты
Это, конечно, очень круто и классно, но можем ли мы создать кортеж каким-то другим способом, не редактируя сам код? - Да, ещё как можно.
4. Преобразованием и другого итерируемого объекта
# Из списка
lst = [1, 2, 3]
tpl = tuple(lst) # (1, 2, 3)
# Из строки
tpl = tuple("привет")
print(tpl) # ('п', 'р', 'и', 'в', 'е', 'т')
# Из словаря, о котором мы поговорим позже
person = {
'name': 'Алексей',
'age': 20
}
tpl = tuple(person)
print(tpl) # ('name', 'age')
# Из range
tpl = tuple(range(1, 6))
print(tpl) # (1, 2, 3, 4, 5)
5. Возврат из функции
def get_val():
x = int(input("Введите значение х: "))
y = int(input("Введите значение y: "))
return x, y # Это кортеж
tpl = get_val()
print(tpl) # (x, y)
Взаимодействие
1. Доступ к элементам
Как и в списках, элементы кортежа доступны по индексу, начиная с 0. Поддерживаются срезы и отрицательная индексация.
tpl = (1, 2, 3, 4, 5)
first = tpl[0] # 1
last = tpl[-1] # 5
sub = tpl[1:3] # (2, 3)
2. Операции с кортежами
Длина кортежа
tpl = (10, 20, 30)
print(len(tpl)) # 3
Объединение кортежей
a = (1, 2)
b = (3, 4)
c = a + b # (1, 2, 3, 4)
print(c)
Повторение кортежей
tpl = ('привет',) * 3
print(tpl) # ('привет', 'привет', 'привет')
3. Преобразование
Кортеж → список
tpl = (1, 2, 3)
lst = list(tpl) # [1, 2, 3]
lst.append(4) # Теперь можно изменять
print(lst) # [1, 2, 3, 4]
Список → кортеж
lst = ['a', 'b', 'c']
tpl = tuple(lst)
print(tpl) # ('a', 'b', 'c')
Строка → кортеж
tpl = tuple("привет")
print(tpl) # ('п', 'р', 'и', 'в', 'е', 'т')
4. Методы
У кортежей всего два метода, потому что они неизменяемы.
.count(x)
— возвращает количество вхождений элементаx
.index(x, y, z)
— возвращает индекс первого вхождения элементаx
, в промежутке оту
доz
не включительно.
tpl = (1, 2, 2, 3, 2)
print(tpl.count(2)) # 3
print(tpl.index(2)) # 1
print(tpl.index(2, 1)) # 1 (поиск начинаем с индекса 1)
Словарь — это структура данных, хранящая пары «ключ: значение», где ключи уникальны и неизменяемы, а значения могут быть любыми и повторяться.
Способы инициализации
Словарь можно создать несколькими способами — с помощью фигурных скобок {}
или встроенной функции dict()
.
1. Пустой словарь
dct = {}
# или так
dct = dict()
2. Словарь с начальными значениями.
Фигурные скобки {}
позволяют явно определить словарь, перечисляя пары ключ-значение через запятую.
dct = {
'ключ 1': 'значение 1',
'ключ 2': 'значение 2'
}
# Также, в качестве значений в словаре могут выступать и другие словари
person = {
'Имя': 'Саня',
'Фамилия': 'Иванов',
'Возраст: 30,
'Профессия': 'Вайбкодер'
'Навыки': ['ChatGPT', 'DeepSeek', 'Qwen'],
'Адрес': {
'Улица': 'Ленина',
'Дом': '74'
}
}
Значения в словаре могут быть любого типа: строки, числа, списки, другие словари и даже функции.
Встроенная функция dict()
позволяет создать словарь, используя другие структуры данных.
Создание из списка кортежей
my_dict = dict([('a', 1), ('b', 2), ('c', 3)])
print(my_dict) # {'a': 1, 'b': 2, 'c': 3}
Создание из списка списков
my_dict = dict([['x', 10], ['y', 20], ['z', 30]])
print(my_dict) # {'x': 10, 'y': 20, 'z': 30}
Создание с помощью именованных аргументов
my_dict = dict(name='Игорь', age=25, city='Москва')
print(my_dict) # {'name': 'Игорь', 'age': 25, 'city': 'Москва'}
Взаимодействие
1. Доступ к элементам
Элементы словаря извлекаются по ключу. Существует несколько методов доступа к значениям по их ключу:
Через квадратные скобки
[]
person = {
'Имя': 'Алексей',
'Страна': 'Россия',
'Навыки': ['Python', 'SQL']
}
print(person['Имя']) # Алексей
print(person['Навыки'][0]) # Python
Через метод
.get()
person = {
'Имя': 'Алексей',
'Страна': 'Россия',
'Навыки': ['Python', 'SQL']
}
print(person.get('Город')) # None
print(person.get('skills')) # ['Python', 'SQL']
Через циклы
person = {
'Имя': 'Алексей',
'Страна': 'Россия',
'Навыки': ['Python', 'SQL']
}
# Выводим пару "ключ: значение" в виде кортежа!
for i in person.items():
print(i)
# ('Имя', 'Алексей')
# ('Страна', 'Россия')
# ('Навыки', ['Python', 'SQL'])
# Выводим значения словаря
for i in person.values():
print(i)
# Алексей
# Россия
# ['Python', 'SQL']
# Выводи ключи словаря
for i in person.keys():
print(i)
# Имя
# Страна
# Навыки
2. Добавление и изменение значений
Добавляем новый ключ
person['Любимый цвет'] = 'Синий'
print(person) # {'Имя': 'Алексей', 'Страна': 'Россия', 'Навыки': ['Python', 'SQL'], 'Любимый цвет': 'Синий'}
Изменяем существующее значение
person['Навыки'].append('С++')
print(person) # {'Имя': 'Алексей', 'Страна': 'Россия', 'Навыки': ['Python', 'SQL', 'С++'], 'Любимый цвет': 'Синий'}
3. Удаление элементов
Существует несколько способов удалить пару «ключ: значение».
person = {
'Имя': 'Алексей',
'Страна': 'Россия',
'Навыки': ['Python', 'SQL']
}
person.pop('Имя') # Удаляет по ключу
print(person) # {'Страна': 'Россия', 'Навыки': ['Python', 'SQL']}
person.popitem() # Удаляет последнюю добавленную пару
print(person) # {'Страна': 'Россия'}
4. Вычисление длины и очистка
person = {
'Имя': 'Алексей',
'Страна': 'Россия',
'Навыки': ['Python', 'SQL']
}
print(len(person)) # 3
print(person.clear()) # {}
5. Копирование словаря
Как и со списками, простое присваивание создаёт ссылку, а не копию. Чтобы создать независимую копию, используем .copy()
.
person = {'name': 'Алексей'}
pers_copy = person.copy()
pers_copy['name'] = 'Ахмед'
print(person) # {'name': 'Алексей'}
print(pers_copy) # {'name': 'Ахмед}
Сравнительная таблица структур данных
Характеристика | Список ( | Кортеж ( | Словарь ( |
---|---|---|---|
Тип | Упорядоченный набор | Упорядоченный набор | Неупорядоченный набор |
Изменяемость | Изменяемый | Неизменяемый | Изменяемый |
Дубликаты | Разрешены | Разрешены | Ключи уникальны Значения могут повторяться |
Доступ к элементам | По целочисленному индексу ( | По целочисленному индексу ( | По ключу ( |
Синтаксис создания |
|
|
|
Пустой объект |
|
|
|
Основное назначение | Хранение упорядоченных данных, которые могут меняться | Хранение фиксированных данных | Хранение пар «ключ → значение» для быстрого доступа |
Если вы дочитали до этого момента, значит, вы прочли статью полностью — с чем я вас поздравляю! Мы разобрали с вами одни из самых распространённых структур данных, которые используются во многих областях: от простых скриптов до сложных веб-приложений.
В следующих частях мы познакомимся с другими не менее важными структурами — такими как множества, стеки, очереди, связные списки, деревья, графы и т.д. Каждая из них решает свои задачи, и каждая обязательно пригодится вам на практике.