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

Список — это абстрактный тип данных, хранящий в себе упорядоченный набор значений. Обозначается через квадратные скобки [].

Способы инициализации

Список можно создавать разными способами — от прямого задания в исходном коде до использования функции 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': 'Ахмед}

Сравнительная таблица структур данных

Характеристика

Список (list)

Кортеж (tuple)

Словарь (dict)

Тип

Упорядоченный набор

Упорядоченный набор

Неупорядоченный набор

Изменяемость

Изменяемый

Неизменяемый

Изменяемый

Дубликаты

Разрешены

Разрешены

Ключи уникальны Значения могут повторяться

Доступ к элементам

По целочисленному индексу (arr[0])

По целочисленному индексу (tpl[0])

По ключу (dct['key'])

Синтаксис создания

[1, 2, 3]

(1, 2, 3) или 1, 2, 3

{'ключ': 'значение'}

Пустой объект

[] или list()

() или tuple()

{} или dict()

Основное назначение

Хранение упорядоченных данных, которые могут меняться

Хранение фиксированных данных

Хранение пар «ключ → значение» для быстрого доступа

Если вы дочитали до этого момента, значит, вы прочли статью полностью — с чем я вас поздравляю! Мы разобрали с вами одни из самых распространённых структур данных, которые используются во многих областях: от простых скриптов до сложных веб-приложений.

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