Learning Platform
Глоссарий Troubleshooting
Урок 03.07 · 15 мин
Продвинутый
SummaryBig-OMemoryDecision matrix

Сравнительная таблица: list/tuple/dict/set big-O и memory

Этот урок — single-page reference card по всему модулю M02. Если вы только что прочитали уроки 01-06, эта страница даёт comparative view: рядом четыре структуры, рядом их operations, рядом их big-O. Используйте перед экзаменом для self-assessment, и в production — как cheat-sheet.


Big-O matrix — ключевые operations

ОперацияlisttupledictsetКомментарий
len(x)O(1)O(1)O(1)O(1)поле ob_size / ma_used / used
indexing x[i]O(1)O(1)n/an/adirect array access (positional)
key lookup x[k]n/an/aO(1) avgn/ahash + probe ~3 шага
append / addamort O(1)n/aO(1) avgO(1) avgmutable only
insert(0, x)O(n)n/an/an/ashift всех elements
x in containerO(n)O(n)O(1) avgO(1) avghash для dict/set
iterationO(n)O(n)O(n)O(n)sequential scan
pop endO(1)n/avariesn/adecrement size
pop frontO(n)n/avariesn/ashift всех
sortO(n log n)n/an/an/aTimsort adaptive
copy / shallowO(n)O(n)O(n)O(n)new container + memcpy указателей
union |n/an/an/aO(s + t)iterate обе
intersection &n/an/an/aO(min(s, t))iterate меньшую
difference -n/an/an/aO(s)iterate s, exclude если in t

Worst case для O(1) avg: O(n) при коллизиях. Mitigation: hash randomization (str/bytes), uniform __hash__.


Memory snapshot (на cpython-3.12.7, 64-bit)

Containerempty1 element10 elements
list56 байт88 байт184 байт
tuple40 байт48 байт120 байт
dict64 байт184 байт~376 байт
set216 байт216 байт (smalltable)216 байт (smalltable)
frozenset216 байт216 байт216 байт

(Точные значения см. scripts/python-course/pyodide-baseline.json.)

Наблюдения:

  • tuple самый компактный (нет capacity headroom, нет allocated поля): 40 + 8N байт точно.
  • list имеет capacity headroom (geometric ~1.125x): 56 + 8 × allocated, не 8 × ob_size.
  • dict тяжелее всех на small-end: 64 байт пустой dict, 184 байт после первого insert (PyDictKeysObject + dk_indices + dk_entries отдельно аллоцированы).
  • set имеет встроенную smalltable размера 8 — для маленьких сетов не нужна отдельная malloc’нутая table; sys.getsizeof остаётся 216 байт до выхода из smalltable.

Decision matrix — что выбрать

Use caseChooseWhy
Ordered mutable sequencelistappend amortized O(1); indexing O(1)
Fixed structured value (record)tuplehashable, immutable signal of structure, packed memory
Lookup by keydictO(1) avg key access
Membership / dedupsetO(1) avg + set ops API
Hashable container (dict key, set element)tuple / frozensethashability requires immutability
Numerical data, largearray.array / NumPyno PyObject overhead per element
Front-ops mutablecollections.dequeO(1) appendleft/popleft
Counter / multisetcollections.Counterdict subclass с increment-aware API
Default dict (auto-init)collections.defaultdictdict с factory для missing keys
Ordered setn/a (use dict.fromkeys)dict insertion order = ordered set

Self-assessment перед экзаменом

Чек-лист (10 пунктов). Проверьте каждое утверждение для себя — если не уверены, перечитайте указанный урок:

  • Я могу нарисовать PyListObject от руки — header, ob_item pointer, separately allocated массив указателей, capacity ≥ ob_size. (M02-01)
  • Я могу прочитать lookdict() в Objects/dictobject.c и объяснить probe sequence: i = (5*i + 1 + perturb) & mask; perturb >>= PERTURB_SHIFT. (M02-03)
  • Я могу нарисовать compact dict layout (PEP 468): dk_indices (sparse, 1/2/4-byte indices) + dk_entries (dense, insertion-ordered (hash, key, value) triples). (M02-04)
  • Я понимаю почему tuple hashable, а list нет — на уровне stable hash invariant: mutable объект, изменив content, ломает inverse-mapping в hash table. (M02-02, M02-06)
  • Я могу объяснить amortized O(1) append через aggregate analysis: total work = O(n) для n appends при geometric growth (1+1.125+…+n/(c-1)·c ≤ 9n при c=1.125). (M02-01)
  • Я могу объяснить почему 'x' in [1M_items] плохо vs set: list — O(n) per check (linear scan), set — O(1) avg per check (hash + probe). Preprocess в set за O(n) one-time, потом O(1) per query. (M02-05)
  • Я знаю когда insertion order для dict стало language guarantee: Python 3.7. Python 3.6 — implementation detail (CPython, PyPy). (M02-04)
  • Я могу объяснить почему immutable cache-friendlier: stable layout (no realloc, no rewrite), packed primitives возможны (NumPy ndarray), zero-copy между процессами (Arrow buffer). (M02-06)
  • Я могу imple linear-probing dict из памяти: hash → slot, while занят чужим key → next slot, либо empty (not found) либо matching (hit). (M02-03 code challenge)
  • Я понимаю как PEP 468 экономит ~30-65% памяти: разделение sparse dk_indices (только индексы) + dense dk_entries (только данные); раньше каждый slot — 24 байта (h, k, v) независимо занят или пуст. (M02-04)

Что в M03

Module 03 (functions / args/kwargs / comprehensions / functional tools) — менее memory-deep, больше idiomatic Python patterns:

  • Function как PyFunctionObject, closures и cell variables
  • *args / **kwargs mechanics — tuple и dict packing
  • Comprehensions vs generator expressions (memory trade-off)
  • map/filter/reduce и functools (lru_cache, partial)
  • Decorators и descriptor protocol

После M03 у вас будет полная картина Python data + control model. M04+ — applied data engineering.


Cross-course context

Колончатый формат: от Python структур к аналитическому движку Arrow Memory Layout: финальная точка эволюции Python структур

Проверьте понимание

Результат: 0 из 0
Прикладной
Вопрос 1 из 4. Сводный: `'x' in s` для `s` типа `list[10**6]` vs `set[10**6]` — какая разница в worst-case по операциям?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 7