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

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

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

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

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

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

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

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

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

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