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

Какие знаешь встроенные структуры данных в Python?

1.6 Junior🔥 261 комментариев
#Python

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

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

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

Встроенные структуры данных в Python

Структуры данных — это фундамент Python программирования. Каждая из них имеет свои характеристики по производительности, использованию памяти и семантике. Data Engineer должен выбирать оптимальную структуру для каждой задачи.

1. List (список)

List — упорядоченная, изменяемая коллекция с возможностью содержать элементы любого типа.

# Создание
my_list = [1, 2, 3, 'hello', 4.5]
empty_list = []
list_from_range = list(range(10))

# Основные операции
my_list.append(5)  # O(1) amortized
my_list.insert(1, 'new')  # O(n)
my_list.extend([6, 7])  # O(k) где k - размер добавляемого списка
my_list.pop()  # O(1) - удаляет последний
my_list.pop(0)  # O(n) - удаляет первый
my_list.remove(2)  # O(n)

# Производительность
# Доступ по индексу: O(1)
first = my_list[0]
last = my_list[-1]

# Поиск элемента: O(n)
index = my_list.index(3)

# Сложность
print(len(my_list))  # O(1)
print(3 in my_list)  # O(n)

# List comprehension
squares = [x**2 for x in range(10) if x % 2 == 0]  # [0, 4, 16, 36, 64]

Когда использовать: когда нужна упорядоченная коллекция с возможностью изменения.

2. Tuple (кортеж)

Tuple — упорядоченная, неизменяемая (immutable) коллекция. Быстрее списка из-за оптимизаций.

# Создание
my_tuple = (1, 2, 3, 'hello')
empty_tuple = ()
single_element = (42,)  # важна запятая!
tuple_from_list = tuple([1, 2, 3])

# Операции
first = my_tuple[0]  # O(1)
length = len(my_tuple)  # O(1)
index = my_tuple.index(2)  # O(n)

# Как ключи словаря (списки не могут быть ключами)
user_position = {(100, 200): 'home'}
print(user_position[(100, 200)])  # 'home'

# Распаковка
x, y, *rest = (1, 2, 3, 4, 5)
print(x, y, rest)  # 1 2 [3, 4, 5]

Когда использовать: когда нужна неизменяемая последовательность, ключи для дictionare/set, или функции возвращают несколько значений.

3. Dictionary (словарь)

Dictionary — неупорядоченное хранилище пар ключ-значение (в Python 3.7+ сохраняет порядок вставки).

# Создание
my_dict = {'name': 'Alice', 'age': 30, 'city': 'Moscow'}
empty_dict = {}

# Из пар
from collections import defaultdict

dict_from_pairs = dict([('a', 1), ('b', 2)])
dict_from_args = dict(name='Bob', age=25)

# Доступ
name = my_dict['name']  # O(1) average
age = my_dict.get('age', 0)  # безопаснее, возвращает default

# Изменение
my_dict['age'] = 31  # O(1) average
my_dict.update({'city': 'SPB', 'country': 'Russia'})

# Удаление
del my_dict['city']  # O(1) average
my_dict.pop('age')  # O(1) average

# Итерация
for key in my_dict:  # только ключи
    print(key)

for key, value in my_dict.items():
    print(f"{key}: {value}")

# Dictionary comprehension
squares = {x: x**2 for x in range(5)}  # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

Когда использовать: для быстрого поиска по ключу, хранения структурированных данных.

4. Set (множество)

Set — неупорядоченная коллекция уникальных элементов. Как математическое множество.

# Создание
my_set = {1, 2, 3, 4, 5}
empty_set = set()  # {} создаст пустой dict!
set_from_list = set([1, 2, 2, 3, 3, 4])  # {1, 2, 3, 4}
set_from_string = set('hello')  # {'h', 'e', 'l', 'o'}

# Операции
my_set.add(6)  # O(1) average
my_set.remove(3)  # O(1) average, выбросит исключение если нет
my_set.discard(10)  # O(1) average, не выбросит ошибку
my_set.pop()  # удаляет произвольный элемент

# Проверка принадлежности
if 3 in my_set:  # O(1) average
    print("Found")

# Операции множеств
set_a = {1, 2, 3}
set_b = {2, 3, 4}

union = set_a | set_b  # {1, 2, 3, 4}
intersection = set_a & set_b  # {2, 3}
difference = set_a - set_b  # {1}
symmetric_diff = set_a ^ set_b  # {1, 4}

# Set comprehension
even_set = {x for x in range(10) if x % 2 == 0}  # {0, 2, 4, 6, 8}

Когда использовать: для проверки принадлежности, удаления дубликатов, операций множеств.

5. Collections — специальные структуры

from collections import defaultdict, Counter, OrderedDict, namedtuple, deque

# defaultdict — словарь с дефолтным значением
graph = defaultdict(list)
graph['A'].append('B')  # не выбросит KeyError

# Counter — подсчёт элементов
words = ['apple', 'banana', 'apple', 'cherry']
word_count = Counter(words)  # Counter({'apple': 2, 'banana': 1, 'cherry': 1})
word_count.most_common(2)  # [('apple', 2), ('banana', 1)]

# namedtuple — кортеж с именованными полями
Point = namedtuple('Point', ['x', 'y'])
point = Point(10, 20)
print(point.x, point.y)  # 10 20

# deque — двусторонняя очередь (очень быстро добавлять/удалять с обоих концов)
from collections import deque
queue = deque([1, 2, 3])
queue.appendleft(0)  # O(1) - добавить в начало
queue.popleft()  # O(1) - удалить из начала
queue.append(4)  # O(1)
queue.pop()  # O(1)

6. Сравнение производительности

ОперацияListTupleDictSet
Доступ по индексуO(1)O(1)--
ПоискO(n)O(n)O(1)*O(1)*
ВставкаO(n)-O(1)*-
УдалениеO(n)-O(1)*O(1)*
ИтерацияO(n)O(n)O(n)O(n)

*Среднее время (average case)

Использование в data engineering

# Пример 1: Batch обработка данных
from collections import deque

def process_batch(data_stream, batch_size=1000):
    batch = deque(maxlen=batch_size)  # autosized queue
    
    for item in data_stream:
        batch.append(item)
        if len(batch) == batch_size:
            yield list(batch)
            batch.clear()
    
    if batch:
        yield list(batch)

# Пример 2: Дедупликация больших наборов
from collections import Counter

def remove_duplicates_large(data_stream):
    seen = set()
    for item in data_stream:
        if item not in seen:
            seen.add(item)
            yield item

# Пример 3: Группировка данных
from collections import defaultdict

def group_by_category(transactions):
    groups = defaultdict(list)
    
    for transaction in transactions:
        groups[transaction['category']].append(transaction)
    
    return dict(groups)

# Пример 4: Top N элементов
from collections import Counter
import heapq

def get_top_n(data, n=10):
    counter = Counter(data)
    return counter.most_common(n)  # O(n log k) где k = n

Memory usage

import sys

# Размер в памяти
print(sys.getsizeof([]))  # ~56 bytes
print(sys.getsizeof(()))  # ~40 bytes (меньше благодаря immutability)
print(sys.getsizeof({}))  # ~240 bytes
print(sys.getsizeof(set()))  # ~200 bytes

# Для больших данных нужно выбирать экономно
# Tuple <- List <- Dict/Set (по затратам памяти)

Best Practices

  • Используй list для упорядоченных изменяемых данных
  • Используй tuple когда данные не меняются или нужны как ключи
  • Используй dict для быстрого поиска по ключу
  • Используй set для проверки принадлежности и уникальности
  • Для очередей (FIFO) используй deque, не list
  • Для подсчёта элементов используй Counter
  • List comprehension и set comprehension быстрее циклов
  • Понимай сложность операций перед выбором структуры
  • Для больших объёмов данных рассмотри numpy arrays или pandas DataFrame