TGViewer
EvApps EvApps @evapps_team · 199 subscribers
Post #1524 88
🧱 Массив там, где нужен был не массив
Почти всё мы решаем массивом и словарём — и обычно норм
Но есть места, где привычная структура на ровном месте начинает тормозить, и на проде это больно
Причина почти всегда одна — взяли не ту структуру под задачу
Собрал частые проблемы и их решения

1. Проверка «есть ли такой элемент» в списке 🐌 Классика:
if user_id in users_list:   # бежит по всему списку

Каждая такая проверка перебирает весь список от начала до конца, пока не найдёт
Один раз — ерунда
А если это внутри цикла по другому списку — получаешь перебор в переборе, и на десятках тысяч элементов всё встаёт
Причём в дебаге ты этого не увидишь
Если тебе нужно только «есть или нет» — бери множество (set):
users = set(users_list)
if user_id in users: # мгновенно, по хэшу

Set устроен так, что находит элемент сразу, не перебирая
Заплатил один раз за построение множества — дальше все проверки почти ничего не стоят

2. Удаление из начала списка ✂️ Тоже коварное:

queue.pop(0)   # весь список сдвигается влево

Удалил первый элемент — и все остальные физически сьехало на одну позицию
На маленьком списке незаметно, а на большом каждый такой pop проходит по всему массиву
Есть deque — очередь, из которой можно быстро брать и с начала, и с конца:
from collections import deque
q = deque()
q.append(x) # в конец
q.popleft() # с начала, без сдвигов

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

3. Считаем, сколько раз что встретилось 🔢
Обычно это пишут руками:

counts = {}
for x in items:
if x in counts:
counts[x] += 1
else:
counts[x] = 1

Знакомо?
А между тем для этого есть готовый инструмент:
from collections import Counter
counts = Counter(items)
counts.most_common(3) # ещё и топ-3 сразу отдаст

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

4. Нужно вытащить десять самых больших значений из миллиона 🗑
sorted(data)[-10:]   # перелопатил всё ради десятки

Ты отсортировал целый массив, чтобы взять с хвоста десять штук — остальные 999 990 отсортировал впустую
Для этого есть куча (heap) — она держит в уме только нужные элементы, а не гоняет весь массив:
import heapq
heapq.nlargest(10, data)

Куче надо следить всего за десятью значениями, поэтому на больших данных она заметно быстрее полной сортировки.
То же и для «топ-N самых маленьких» — nsmallest

5. Группировка с вечной проверкой «а есть уже такой ключ?» 🏗
groups = {}
for user in users:
if user.city not in groups:
groups[user.city] = []
groups[user.city].append(user)

defaultdict убирает всю эту возню:
from collections import defaultdict
groups = defaultdict(list)
for user in users:
groups[user.city].append(user) # пустой список создастся сам

Просишь ключ, которого нет — он сам подставит пустой список, и можно сразу пихать
Тот же приём с defaultdict(int) для счётчиков, если Counter почему-то не подходит

А как часто вы используете это или пишите по старинке? 🤔

#algorithms #python #performance #backend #dev #programming
More from @evapps_team
  1. Sep 21, 2026🧩 Что тут не так? Код-загадка Формат новый - показываю код, ты угадываешь подвох, ниже ра…
  2. Sep 18, 2026🎭 Мифы про производительность, в которые верят даже опытные Миф 1: "Меньше строк кода - б…
  3. Sep 16, 2026🚨 Как перевод денег уронил нам прод ⏰ 19:10 Задеплоили долгожданное - переводы между коше…
  4. Sep 14, 2026🗃 Кэш поставили, а он отдаёт старьё В программировании две сложные вещи - инвалидация кэш…
  5. Sep 11, 2026🔌 "Too many connections" - и почему база падает под нагрузкой Под нагрузкой прилетает FAT…
  6. Sep 11, 2026Пока вы наслаждаетесь пятницей, мы напоминаем, что уже завтра стартует одна из наших любим…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →