Генераторы списков и встроенные функции: вопросы для собеседования (часть 2)
List comprehensions, dict comprehensions, map, filter, zip, enumerate — идиоматический Python, который ожидают от аналитика. На собеседовании просят переписать цикл в comprehension, использовать sorted с ключом или объяснить разницу между map и генератором списка. Владение этими конструкциями показывает зрелость как Python-разработчика.
Вопросы 6–10 из 20
6Нужно преобразовать `user_ids = [1, -1, 2]` в список строк только для положительных значений. Какой вариант обычно читается проще?
A`[str(x) for x in user_ids if x > 0]`
B`list(map(str, filter(lambda x: x > 0, user_ids)))`
C`map(str, user_ids)`
D`filter(lambda x: str(x) > 0, user_ids)`
Ответ: Когда нужно и отфильтровать, и преобразовать элементы, list comprehension часто читается прямее, чем `filter()` + `map()` с `lambda`.
Вариант `[str(x) for x in user_ids if x > 0]` выглядит как обычная формулировка задачи: «возьми `str(x)` для каждого `x`, если `x > 0`». Вариант с `map()`/`filter()` добавляет вложенность и анонимную функцию, что усложняет чтение.
7Дан список `vals = [0, 1, 2]`. Что вернёт выражение `[x if x % 2 == 0 else -1 for x in vals]`?
A`[0, 1, 2]`
B`[-1, -1, -1]`
C`[0, 2]`
D`[0, -1, 2]`
Ответ: Тернарное выражение внутри comprehension (`a if cond else b`) помогает заменить `if/else` без отдельного цикла.
Для каждого `x` из `vals` проверяется условие `x % 2 == 0`. Если оно истинно, в результат попадает сам `x`, иначе — `-1`. Так можно сделать преобразование с ветвлением в одну строку, сохраняя понятную структуру.
8У вас есть список словарей `users` с ключами `id` и `is_active`. Нужно получить список `id` только активных пользователей. Какое решение обычно проще читать, чем комбинация `map()` + `filter()` с `lambda`?
A`[u["id"] for u in users if u.get("is_active")]`
B`list(map(lambda u: u["id"], filter(lambda u: u.get("is_active"), users)))`
C`any(u.get("is_active") for u in users)`
D`{u["id"]: u for u in users}`
Ответ: Когда одновременно есть фильтрация и преобразование, list comprehension обычно читается прямее, чем связка `filter()` и `map()`.
List comprehension позволяет выразить намерение в одном шаблоне: «для каждого элемента, если условие истинно, добавь вычисленное значение». Вариант с `map()`/`filter()` и `lambda` часто тяжелее для чтения из-за вложенности и двух анонимных функций.
9Нужно проверить, что все значения в `prices` строго положительные. Какое выражение вернёт `True` только если все элементы больше 0?
A`any(p > 0 for p in prices)`
B`[p > 0 for p in prices]`
C`sum(p > 0 for p in prices)`
D`all(p > 0 for p in prices)`
Ответ: `all()` возвращает `True`, только если все проверки в генераторе истинны.
Конструкция `all(p > 0 for p in prices)` не создаёт промежуточный список, а последовательно проверяет элементы и возвращает `False`, как только встречает не подходящее значение. Вариант с `any()` отвечает на другой вопрос: «есть ли хотя бы один положительный».
10Есть список строк `raw = ["10", "", "3"]`. Нужно получить список целых чисел только из непустых строк. Какой вариант корректен и читаем?
A`list(map(int, raw))`
B`list(filter(None, map(int, raw)))`
C`[int(x) for x in raw if x]`
D`filter(int, raw)`
Ответ: Comprehension удобно объединяет фильтрацию (`if x`) и преобразование (`int(x)`) без вложенных вызовов.
List comprehension `[int(x) for x in raw if x]` сначала отбрасывает пустые строки, а затем применяет `int(x)` только к оставшимся. Варианты, которые сначала пытаются выполнить `int()` для всех элементов, могут упасть на пустой строке.
Хотите тренировать интерактивно?
В приложении — таймер, прогресс, стрики и 1700+ вопросов по всем темам.
Тренировать в Telegram