Prosto Python | вопросы с собесов
363 subscribers
184 photos
1 video
2 files
566 links
🚀 Python-собесы без сюрпризов! Разбираем реальные вопросы, ошибки кандидатов и лайфхаки, которые помогают пройти интервью. Джун → мидл → сеньор — прокачивайся и разнеси следующий собес! 🔥
Download Telegram
🧰 Code Cleanup — выпуск 17
Тема: не делай лишние проходы по данным


Код может быть «чистым» на вид, но при этом дорогим по производительности.
Особенно часто это встречается при работе со списками.


До (лишние проходы):

numbers = [1, 2, 3, 4, 5, 6]

evens = []
for n in numbers:
if n % 2 == 0:
evens.append(n)

squares = []
for n in evens:
squares.append(n * n)


Два цикла.
Два прохода.


После (один проход):
squares = [n * n for n in numbers if n % 2 == 0]


🧠 Почему это лучше:

🔹 один проход вместо двух

🔹 меньше кода

🔹 проще читать

🔹 быстрее на больших данных

🐍Вопросы с собесов -> ProstoPython
👍4
🐍 Python Style
Тема: with open() вместо ручного закрытия файлов

Один из самых простых способов сделать код безопаснее —
не закрывать файлы вручную.

Плохой стиль:

file = open("data.txt", "r")
data = file.read()
file.close()


Что может пойти не так?
Если между open() и close() упадёт ошибка — файл останется открыт.


Python Style:

with open("data.txt", "r") as file:
data = file.read()


🧠 Почему так лучше:

🔹 файл закроется автоматически

🔹 код короче и чище

🔹 безопасно при ошибках

🔹 стандарт де-факто в Python

🐍Вопросы с собесов -> ProstoPython
🔥4
Объект первого класса — это сущность, с которой можно обращаться так же, как с обычными значениями.

🔹 присваивать переменной
🔹 передавать как аргумент функции
🔹 возвращать из функции
🔹 хранить в структурах данных

В Python функции, классы и типы являются объектами первого класса.

🐍Вопросы с собесов -> ProstoPython
🔥4
Оценка сложности O(n) возникает, когда время работы алгоритма растёт линейно от количества входных данных — каждая операция выполняется один раз для каждого элемента.

O(n²) появляется, когда для каждого элемента выполняется полный проход по всем остальным (например, вложенные циклы).

O(n) предпочтительнее, потому что при росте данных время выполнения увеличивается гораздо медленнее: при больших n линейный алгоритм работает на порядки быстрее квадратичного.

🐍Вопросы с собесов -> ProstoPython
👍3
🐍 Python Style
Тема: не используй range(len(...)), если можно проще


Очень частый паттерн у начинающих — и почти никогда у опытных Python-разработчиков 👀

Не по-питоничному:

for i in range(len(users)):
print(users[i])


Работает, но выглядит как перенос кода из других языков.


Python Style:
for user in users:
print(user)


А если нужен и индекс, и значение:
for i, user in enumerate(users):
print(i, user)


🧠 Почему так лучше:

🔹 меньше шума

🔹 меньше ошибок с индексами

🔹 код читается как обычный текст

🔹 Python создан именно для такого стиля

🐍Вопросы с собесов -> ProstoPython
🔥3
🐍 Python Style
Тема: используй any() и all() вместо ручных проверок

Иногда в коде встречаются такие конструкции 👇
Работают, но выглядят громоздко и утомительно.


Не по-питоничному:
has_negative = False
for x in numbers:
if x < 0:
has_negative = True
break


Python Style:
has_negative = any(x < 0 for x in numbers)


И наоборот — если нужно проверить все элементы:

all_positive = all(x > 0 for x in numbers)


🧠 Почему это хороший стиль:

🔹 короче и выразительнее

🔹 сразу видно намерение

🔹 работает лениво (эффективно)

🔹 меньше вспомогательных переменных

🐍Вопросы с собесов -> ProstoPython
👍4🔥2
🧰 Code Cleanup — выпуск 18
Тема: убираем магические числа из кода


Магические числа — это числа, которые появляются в коде без объяснения.
Например:

Плохо:
if user.age >= 18:
allow_access()


Что значит 18? Почему именно 18? 🔍


Code Cleanup:
ADULT_AGE = 18

if user.age >= ADULT_AGE:
allow_access()


Теперь понятно, что это за число, и если правила изменятся — достаточно поменять константу в одном месте.

🧠 Почему так лучше:

🔹 код читается сразу

🔹 проще поддерживать

🔹 меньше ошибок при изменениях

🔹 понятнее для команды и ревьюеров

🐍Вопросы с собесов -> ProstoPython
🏆4👍1
🐍 Python Style
Тема: используй set для проверок вхождения


Часто нужно проверить, есть ли элемент в коллекции 👇
Работает, но можно сделать быстрее и чище.


Не по-питоничному:

items = [1, 3, 5, 7, 9]

if x in items:
print("Найдено")


(Особенно больно, если список большой)
Python Style:


items = {1, 3, 5, 7, 9}

if x in items:
print("Найдено")


🧠 Почему это хороший стиль:
🔹 проверка in за O(1), а не O(n)
🔹 код сразу говорит: «мне важна уникальность и поиск»
🔹 меньше скрытых проблем с производительностью
🔹 идеально для фильтров, флагов, whitelists / blacklists

📌 Запомни:
list — когда важен порядок
set — когда важна скорость и уникальность

🐍Вопросы с собесов -> ProstoPython
🔥4👍2
Попробуйте ответить без запуска кода, разбор будет через 2 часа

🐍Вопросы с собесов -> ProstoPython
👍3
Правильный ответ
Правильный вариант:


[1]
[1, 2]
[1, 2, 3]


🧠 Почему именно так

Подвох в значении по умолчанию аргумента items=[].

В Python:

🔷 значения аргументов по умолчанию
🔷 создаются один раз — в момент определения функции
🔷 и переиспользуются при каждом вызове

То есть items — это один и тот же список для всех вызовов add_item.

Что происходит пошагово:

1️⃣ add_item(1)
🔷 список был пуст
🔷 добавили 1
🔷 [1]

2️⃣ add_item(2)
🔷 это тот же самый список
🔷 добавили 2
🔷 [1, 2]

3️⃣ add_item(3)
🔷 снова тот же объект
🔷 [1, 2, 3]

Накидайте 🔥, если было полезно и интересно

🐍Вопросы с собесов -> ProstoPython
🔥5
🧰 Code Cleanup — выпуск 19
Тема: почему else иногда лишний?


Часто в коде можно увидеть такую конструкцию:

Плохо:

if user.is_banned:
return "Access denied"
else:
return "Welcome"


else здесь технически не нужен, но визуально утяжеляет код.
Читать приходится дольше, чем нужно 👀


Code Cleanup:

if user.is_banned:
return "Access denied"
return "Welcome"


Логика та же, но код стал проще и прямолинейнее.

🧠 Почему так лучше:
🔹 меньше уровней вложенности
🔹 код читается сверху вниз
🔹 проще добавлять новые условия
🔹 легче поддерживать и рефакторить

🐍Вопросы с собесов -> ProstoPython
👍6
🧰 Code Cleanup — выпуск 20
Тема: почему временные переменные — лишние

Иногда код усложняют переменные, которые живут пару строк и не несут смысла.

Плохо:

result = user.balance * 0.9
return result


Работает, но переменная здесь ничего не объясняет и только засоряет код.

Code Cleanup:

return user.balance * 0.9


🧠 Почему так лучше:
🔹 меньше шума в коде
🔹 сразу видно, что возвращается
🔹 проще читать и поддерживать
🔹 меньше мест для ошибок

🐍Вопросы с собесов -> ProstoPython
🔥5
Dict comprehension — это краткий способ создания словаря на основе итерируемого объекта.

Пример:

numbers = [1, 2, 3, 4]

squares = {n: n**2 for n in numbers}

print(squares)


Результат:

{1: 1, 2: 4, 3: 9, 4: 16}


Можно добавлять условия:

even_squares = {n: n**2 for n in numbers if n % 2 == 0}


Создаёт словарь только из чётных чисел.

🐍Вопросы с собесов -> ProstoPython
👍5
Новая рубрика в канале — Rookie Mistakes

Рубрика про типичные ошибки, которые делают начинающие Python-разработчики.
Показываем, как делать не стоит, и сразу разбираем, как писать правильно и чище 🐍

Мы постоянно работаем над качеством контента, ищем лучшие примеры и придумываем новые форматы, чтобы тебе было проще расти как разработчику и увереннее чувствовать себя на собеседованиях 🚀

👉 Делись с друзьями и коллегами — пусть меньше людей наступает на одни и те же грабли 😉

🐍Вопросы с собесов -> ProstoPython
🔥41
Rookie Mistakes #1 — list как аргумент по умолчанию

Кажется безобидно, но это одна из самых коварных ошибок в Python 😬

Плохо
def add_item(item, items=[]):
items.append(item)
return items

print(add_item(1)) # [1]
print(add_item(2)) # [1, 2] 😱


Почему так?
items создаётся один раз, а не при каждом вызове функции.


Хорошо

def add_item(item, items=None):
if items is None:
items = []
items.append(item)
return items

print(add_item(1)) # [1]
print(add_item(2)) # [2]


🐍Вопросы с собесов -> ProstoPython
🔥6
gather() используется в asyncio для одновременного запуска и ожидания нескольких асинхронных задач.

🔹 запускает корутины параллельно
🔹 дожидается завершения всех задач
🔹 возвращает результаты в том же порядке, что и переданные задачи

Применяется, когда нужно выполнить несколько асинхронных операций одновременно.

🐍Вопросы с собесов -> ProstoPython
🏆3
Попробуйте ответить без запуска кода, разбор будет через 2 часа

🐍Вопросы с собесов -> ProstoPython
👍41🥰1
Что выведет код выше?
Anonymous Poll
49%
10
22%
5
11%
None
19%
Ошибка
👍1👎1🥰1
Правильный ответ: Ошибка — UnboundLocalError

🧠 Почему так?


🔷Внутри foo() есть присваивание x = 5

🔷Python считает x локальной переменной во всей функции

🔷Но print(x) идёт до присваивания

🔷В итоге: обращение к локальной переменной до её создания -> ошибка

Как исправить, если нужен внешний x:

def foo():
global x
print(x)
x = 5


Или лучше так:

def foo(x):
print(x)
x = 5


🔹 Вывод:
👉 Если в функции есть присваивание — переменная становится локальной, даже если она объявлена снаружи.


🐍Вопросы с собесов -> ProstoPython
🔥51🥰1😁1
🧰 Code Cleanup — выпуск 21
Тема: лишний else после return


Если функция уже что-то вернула — else чаще всего не нужен.

Плохо:
def is_even(n):
if n % 2 == 0:
return True
else:
return False


Код работает, но else здесь — просто шум.

Code Cleanup:
def is_even(n):
return n % 2 == 0


🧠 Почему так лучше:
🔹 меньше строк — быстрее читается
🔹 нет лишней вложенности
🔹 проще логика

🐍Вопросы с собесов -> ProstoPython
👍31