list/tuple/dict/set вместо массивов и struct: что выбрать и почему
core выбрать подходящую встроенную коллекцию Python для конкретной структуры данных, которую вы раньше реализовали бы вручную в C
В C структура данных — это решение о раскладке байтов в памяти: struct фиксирует набор полей, массив фиксирует размер и тип элементов, хеш-таблицу вы пишете сами (массив бакетов + список коллизий + функция хеширования). В Python выбор коллекции — это не решение о памяти, а решение о семантике: изменяемо это или нет, важен ли порядок, нужен ли доступ по ключу, допустимы ли дубликаты. Память и хеширование интерпретатор берёт на себя.
Четыре встроенные коллекции и их роль:
list— динамическая, изменяемая, гетерогенная последовательность; растёт и уменьшается сама, безrealloc.tuple— неизменяемая последовательность: «запись», единое целое; хешируем, поэтому годится в ключиdictи элементыset.dict— встроенная хеш-таблица «ключ → значение», в среднем O(1) на доступ.set— хранение уникальных элементов и быстрая проверка принадлежности, в среднем O(1).
Соответствие с тем, что вы писали руками в C:
| Что вы писали в C | Замена в Python | Почему |
|---|---|---|
int arr[N] фиксированного размера |
list |
растёт и уменьшается сам, без realloc |
struct point { int x, y; } как неизменяемая запись |
tuple |
фиксированный набор полей, неизменяем, хешируем |
| ручная hash table (массив бакетов + linked list коллизий) | dict |
в среднем O(1), без своей функции хеширования |
| bitset или сортированный массив + bsearch для проверки принадлежности | set |
проверка in в среднем O(1), без сортировки и бинарного поиска |
Типичные ловушки C-программиста:
- Видеть
listиtupleкак «два синтаксиса для массива» и всегда братьlist«на всякий случай изменяемый».tupleговорит читателю и интерпретатору: этот набор значений — единое целое и не изменится; бонусом он хешируем (хеш ключа должен быть стабилен, а изменяемый объект такой стабильности не даёт). - «Свой dict» через два параллельных списка (
keys[],values[]) и линейный поиск индекса — прямой перенос C-паттерна «массив структур + перебор», убивающий главное преимущество словаря. listтам, где нужна уникальность и быстрая проверка принадлежности:x in my_list— линейный перебор,x in my_set— хеш-поиск.
Разобранный пример
Задача: посчитать частоту слов в тексте — в C вы решали бы её через массив struct { char* word; int count; } и линейный (или самописный hash) поиск при каждом слове.
Наивный «переведённый C»:
words = text.split()
entries = [] # список [слово, счётчик]
for w in words:
found = False
for e in entries:
if e[0] == w:
e[1] += 1
found = True
break
if not found:
entries.append([w, 1])
Это O(n·m) — при каждом слове линейный перебор накопленных записей. Идиоматично:
from collections import Counter
counts = Counter(text.split())
Даже без Counter обычный dict через counts[w] = counts.get(w, 0) + 1 уже правильное направление — суть в том, что ключевой доступ заменяет линейный перебор.
Попробуй сейчас
У вас есть код на «переведённом C»:
names = ["Ann", "Bob", "Cid"]
ages = [30, 25, 41]
def age_of(name):
for i in range(len(names)):
if names[i] == name:
return ages[i]
return None
Перепишите это без параллельных списков и без линейного поиска, используя одну коллекцию Python. Ожидаемый результат: age_of("Bob") работает за счёт прямого доступа по ключу, без цикла.
Получилось, если…
Вы справились, если решение — это dict вида {"Ann": 30, "Bob": 25, "Cid": 41} с доступом через ages.get(name), и вы можете объяснить, почему это быстрее исходного варианта при большом количестве имён (в среднем O(1) против O(n) на каждый запрос).
Вывод
list — для изменяемой последовательности, tuple — для неизменяемой записи (и как ключ dict), dict — вместо любой ручной hash table, set — вместо ручной проверки уникальности/принадлежности. Выбор коллекции в Python кодирует смысл данных, а не их раскладку в памяти.
AI-generated · source-grounded review
🛡 Fact-checked: 3 risky claims verified · 2 removed · confidence: high · figures: 1 · a second model checked these claims and agreed
On your own course these buttons answer instantly, quizzes track what you've mastered, and lessons adapt to your gaps. Write my course