← Назад к вопросам

Какие знаешь мутабельные структуры данных?

1.2 Junior🔥 141 комментариев
#Python Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Мутабельные структуры данных в Python

Мутабельные (изменяемые) структуры данных — это те, которые можно модифицировать после создания. Это основные типы в Python.

1. List (Список)

Это самая универсальная мутабельная структура. Хранит элементы в порядке:

# Создание
my_list = [1, 2, 3, 'string', 3.14]

# Добавление
my_list.append(4)  # [1, 2, 3, 'string', 3.14, 4]
my_list.extend([5, 6])  # Добавляет несколько элементов
my_list.insert(0, 0)  # Вставляет в позицию 0

# Удаление
my_list.remove(2)  # Удаляет первое вхождение значения 2
my_list.pop()  # Удаляет и возвращает последний элемент
my_list.pop(0)  # Удаляет и возвращает элемент по индексу
my_list.clear()  # Очищает список

# Изменение
my_list[0] = 100  # Присваивает новое значение
my_list[1:3] = [10, 20]  # Срез

# Сортировка (изменяет список на месте)
my_list.sort()  # Сортирует по умолчанию
my_list.sort(reverse=True)  # Сортирует в обратном порядке
my_list.reverse()  # Разворачивает список

Сложность:

  • Append: O(1) амортизированная
  • Insert в конец: O(1)
  • Insert в середину: O(n)
  • Pop с конца: O(1)
  • Pop с начала: O(n)

2. Dictionary (Словарь)

Хранит пары ключ-значение. Очень быстрый поиск:

# Создание
my_dict = {'name': 'John', 'age': 30, 'city': 'NYC'}
my_dict = dict(name='John', age=30)

# Добавление
my_dict['email'] = 'john@example.com'  # Новый ключ
my_dict.setdefault('phone', '+1-555-0123')  # Добавляет если не существует

# Обновление
my_dict['age'] = 31  # Изменяет значение
my_dict.update({'age': 31, 'country': 'USA'})  # Обновляет несколько

# Удаление
del my_dict['email']  # Удаляет по ключу
value = my_dict.pop('phone')  # Удаляет и возвращает значение
my_dict.clear()  # Очищает словарь

# Проверка
if 'name' in my_dict:
    print(my_dict['name'])

# Получение с default
value = my_dict.get('phone', '+1-999-9999')  # Возвращает default если нет

Сложность:

  • Get/Set/Delete: O(1) в среднем случае
  • Collision handling: O(n) в худшем

3. Set (Множество)

Хранит уникальные элементы без порядка. Очень быстрая проверка наличия:

# Создание
my_set = {1, 2, 3, 4, 5}
my_set = set([1, 2, 2, 3])  # {1, 2, 3} — дубликаты удалены
empty_set = set()  # {} — пустой словарь, нужен set()

# Добавление
my_set.add(6)  # Добавляет один элемент
my_set.update([7, 8, 9])  # Добавляет несколько

# Удаление
my_set.remove(5)  # Ошибка если не существует
my_set.discard(5)  # Без ошибки
value = my_set.pop()  # Удаляет и возвращает произвольный элемент
my_set.clear()  # Очищает

# Операции над множествами
set1 = {1, 2, 3}
set2 = {3, 4, 5}

intersection = set1 & set2  # {3} — пересечение
union = set1 | set2  # {1, 2, 3, 4, 5} — объединение
difference = set1 - set2  # {1, 2} — разность
sym_diff = set1 ^ set2  # {1, 2, 4, 5} — симметрическая разность

Сложность:

  • Add/Remove/Contains: O(1) в среднем
  • Intersection/Union: O(len(s1) + len(s2))

4. Bytearray

Изменяемый аналог bytes для работы с бинарными данными:

# Создание
my_bytearray = bytearray(b'hello')
my_bytearray = bytearray(5)  # [0, 0, 0, 0, 0]

# Изменение
my_bytearray[0] = 72  # my_bytearray[0] = 'H'
my_bytearray[1:3] = b'EL'  # Замена диапазона

# Добавление
my_bytearray.append(33)  # Добавляет один байт
my_bytearray.extend(b' world')  # Добавляет несколько

# Удаление
del my_bytearray[0]  # Удаляет байт по индексу
my_bytearray.pop()  # Удаляет и возвращает последний

5. Deque (Double-ended queue)

Оптимизирована для добавления/удаления с обоих концов:

from collections import deque

# Создание
my_deque = deque([1, 2, 3, 4, 5])
my_deque = deque(maxlen=3)  # Максимум 3 элемента, старые удаляются

# Добавление
my_deque.append(6)  # Добавляет в конец
my_deque.appendleft(0)  # Добавляет в начало
my_deque.extend([7, 8])  # Добавляет несколько в конец
my_deque.extendleft([0, -1])  # Добавляет в начало

# Удаление
value = my_deque.pop()  # Удаляет с конца
value = my_deque.popleft()  # Удаляет с начала
my_deque.remove(3)  # Удаляет первое вхождение значения
my_deque.clear()  # Очищает

# Ротация
my_deque.rotate(1)  # Вращает на 1 позицию вправо
my_deque.rotate(-1)  # Вращает на 1 позицию влево

Сложность:

  • Append/Pop с концов: O(1)
  • Append/Pop с середины: O(n)

6. Counter (Счётчик)

Специализированный словарь для подсчёта элементов:

from collections import Counter

# Создание
my_counter = Counter('abracadabra')
# Counter({'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1})

my_counter = Counter(['apple', 'banana', 'apple', 'cherry'])
# Counter({'apple': 2, 'banana': 1, 'cherry': 1})

# Добавление
my_counter['apple'] += 1
my_counter.update(['apple', 'banana'])  # Увеличивает счётчики

# Удаление
my_counter.subtract(['apple'])  # Уменьшает счётчики
my_counter['unknown']  # Возвращает 0 если нет

# Самые частые
my_counter.most_common(2)  # [(элемент, количество), ...]

# Операции
sum(my_counter.values())  # Общее количество элементов

7. DefaultDict

Словарь с default значением для новых ключей:

from collections import defaultdict

# Создание с default list
my_dict = defaultdict(list)
my_dict['colors'].append('red')
my_dict['colors'].append('blue')
# {'colors': ['red', 'blue']}

# Создание с default int
my_dict = defaultdict(int)
my_dict['a'] += 1
# {'a': 1}

# Кастомная функция default
my_dict = defaultdict(lambda: 'unknown')
my_dict['key']  # 'unknown'

8. ChainMap

Комбинирует несколько словарей:

from collections import ChainMap

dict1 = {'a': 1, 'b': 2}
dict2 = {'c': 3, 'd': 4}

chain = ChainMap(dict1, dict2)
chain['a']  # 1 (из dict1)
chain['c']  # 3 (из dict2)
chain['x'] = 10  # Добавляет в первый словарь (dict1)

Сравнение и выбор структуры

# Если нужен упорядоченный список с быстрым доступом
data = [1, 2, 3, 4, 5]  # List

# Если нужно хранить пары ключ-значение
user = {'name': 'John', 'age': 30}  # Dict

# Если нужно хранить уникальные элементы
tags = {'python', 'django', 'fastapi'}  # Set

# Если нужно работать с обоими концами
queue = deque([1, 2, 3])  # Deque

# Если нужно подсчитать элементы
freq = Counter('aaabbc')  # Counter

# Если нужно кластеризировать данные
groups = defaultdict(list)  # DefaultDict

Изменяемость vs Неизменяемость

# Мутабельные (изменяемые)
mutable = [1, 2, 3]
mutable[0] = 100  # OK

# Иммутабельные (неизменяемые)
immutable = (1, 2, 3)
immutable[0] = 100  # TypeError!

# Мутабельные объекты опасны как ключи словарей
my_dict = {(1, 2): 'tuple'}  # OK
my_dict[[1, 2]] = 'list'  # TypeError! List не может быть ключом

Best Practices

1. Используй правильную структуру

  • List — если нужен порядок
  • Set — если нужна скорость проверки
  • Dict — если нужны ключ-значение

2. Будь осторожен с передачей

# ОПАСНО: изменение влияет на исходный список
def modify_list(lst):
    lst[0] = 100

original = [1, 2, 3]
modify_list(original)  # original изменена!

# БЕЗОПАСНО: копирование
def modify_list(lst):
    lst = lst.copy()  # Или lst[:]
    lst[0] = 100  # Не влияет на исходный

3. Понимай сложность операций

  • List.insert(0, x) — O(n), медленно!
  • Deque.appendleft(x) — O(1), быстро

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

Какие знаешь мутабельные структуры данных? | PrepBro