Циклы и условия: вопросы для собеседования (часть 3)

for, while, if/elif/else, break, continue — управление потоком выполнения программы. Задачи на циклы проверяют умение итерироваться по сложным структурам, обрабатывать граничные случаи и писать читаемую логику. Часто дают задачу, где нужно обойти вложенные данные или реализовать несложный алгоритм.

Коллекции и структуры данныхГенераторы списков и встроенные функцииИсключения и отладкаРабота с файлами: JSON и CSVФункции и аргументыИтераторы и генераторыNumPy: основыPandas и DataFrameСинтаксис и типы данных

Вопросы 1115 из 20

11Нужно сегментировать пользователей по `orders_cnt`: 0 → `'new'`, 1–4 → `'low'`, 5+ → `'high'`. Какой порядок условий в цепочке `if`/`elif`/`else` корректный?
AСначала `if orders_cnt == 0` для `'new'`, затем `elif orders_cnt < 5` для `'low'`, иначе `'high'`
BСначала `if orders_cnt < 5` для `'low'`, затем `elif orders_cnt == 0` для `'new'`, иначе `'high'`
CСначала `if orders_cnt > 0` для `'low'`, затем `elif orders_cnt >= 5` для `'high'`, иначе `'new'`
DСначала `if orders_cnt == 0` для `'new'`, затем отдельный `if orders_cnt < 5` для `'low'`, иначе `'high'`
Ответ: Более специфичное условие (0 заказов) проверяйте раньше более общего (`orders_cnt < 5`).

Если начать с `orders_cnt < 5`, значение 0 попадёт в этот сегмент и ветка для нулевых заказов уже не сработает. Правильный порядок — сначала выделить частный случай `orders_cnt == 0`, затем проверить диапазон 1–4 через `orders_cnt < 5`, а всё остальное отдать в `else` как 5+. Замена `elif` на отдельный `if` ломает взаимоисключение веток и тоже даёт неверные сегменты.

Подробный разбор →
12Какой фрагмент `while` вероятнее всего приведёт к бесконечному циклу, если список `events` непустой?
A`i = 0; while i < len(events): i += 1`: счётчик растёт и условие в какой-то момент становится ложным
B`i = 0; while i < len(events): pass`: счётчик не меняется, условие остаётся истинным на каждой итерации
C`i = 0; while i < len(events): i = i + 1`: счётчик растёт обычным присваиванием и цикл завершается
D`i = 0; while i < len(events): break`: цикл прерывается на первой итерации до проверки условия
Ответ: В `while` состояние, влияющее на условие, должно меняться, иначе цикл не завершится.

Главное правило `while` — состояние, влияющее на условие, должно меняться внутри тела цикла. В варианте с `pass` счётчик `i` никогда не увеличивается, поэтому условие `i < len(events)` всегда истинно и цикл не завершится. Варианты с `i += 1` и `i = i + 1` эквивалентны и корректно завершаются. `break` сразу выходит из цикла на первой итерации, никакого зависания не будет.

Подробный разбор →
13Чему будет равна переменная `steps` после выполнения кода: `n = 5`; `steps = 0`; затем цикл `while n > 0:`; внутри выполняется `n -= 2` и `steps += 1`?
A3
B2
C5
D4
Ответ: Число итераций цикла `while` зависит от того, как меняется переменная в условии и через сколько шагов условие станет ложным.

Значения `n` по итерациям: 5 → 3 → 1 → -1. Условие `n > 0` истинно для 5, 3 и 1, поэтому тело цикла выполнится 3 раза, и `steps` увеличится трижды. Если бы шаг был `n -= 1`, итераций было бы 5; если бы условие было `n >= 0`, итераций было бы 4. Поэтому важно мысленно прокрутить переменную по шагам, а не считать стартовое значение.

Подробный разбор →
14Вы обходите список `users` и хотите, чтобы `i` был индексом, а `u` — значением, без использования `range(len(users))`. Какой вариант подходит лучше всего?
A`for u in users: i = users.index(u)`: ищет индекс через `.index()` на каждой итерации
B`for i, u in enumerate(users): print(i, u)`: `enumerate()` сразу даёт пару индекс и значение
C`for i in range(len(users)): u = users[i]`: ручная работа с длиной и индексами вместо итерации
D`for i, u in zip(users, range(len(users))): print(i, u)`: индекс и значение перепутаны местами
Ответ: `enumerate()` даёт индекс и элемент в одной итерации и не требует ручной работы с длиной и индексами.

`enumerate(users)` читабельнее и безопаснее, чем `range(len(users))`: возвращает пару `(индекс, элемент)` напрямую. Вариант с `users.index(u)` даёт неверные индексы при дубликатах и работает за квадратичное время. В варианте с `zip(users, range(len(users)))` аргументы перепутаны местами — `i` будет значением, а `u` — индексом.

Подробный разбор →
15Списки разной длины: `a = ['u1', 'u2', 'u3']` и `b = [10, 20]`. Код: `pairs = []`; затем `for x in zip(a, b):`; внутри `pairs.append(x)`. Сколько элементов будет в `pairs`?
A`3`: `zip` повторит последний элемент короткой последовательности до длины более длинной
B`1`: `zip` создаёт только одну пару из самых первых элементов входных последовательностей
C`0`: при разной длине входных последовательностей `zip` возвращает пустой результат
D`2`: `zip` останавливается на самой короткой последовательности, лишний элемент `'u3'` отброшен
Ответ: `zip()` останавливается на самой короткой последовательности.

`zip(a, b)` сформирует пары только для первых двух элементов: (`'u1'`, 10) и (`'u2'`, 20). Элемент `'u3'` не попадёт в результат, потому что в `b` нет третьего значения. Если нужно обработать все элементы и заполнить пропуски, используется `itertools.zip_longest`, который дополняет короткую последовательность до длины самой длинной.

Подробный разбор →
1234

Хотите тренировать интерактивно?

В приложении — таймер, прогресс, стрики и 1700+ вопросов по всем темам.

Тренировать Python в Telegram

Другие темы: Python

Коллекции и структуры данныхГенераторы списков и встроенные функцииИсключения и отладкаРабота с файлами: JSON и CSVФункции и аргументыИтераторы и генераторыNumPy: основыPandas и DataFrameСинтаксис и типы данных