Вопросы по теме «Итераторы и генераторы»

yield, генераторные выражения, протокол итератора (__iter__, __next__) — продвинутый Python, который спрашивают у кандидатов на middle+. Генераторы экономят память при обработке больших данных. На собеседовании просят объяснить ленивое вычисление, написать генератор или показать разницу между списком и генератором.

Всего в этом разделе 20 вопросов. Каждый — с правильным ответом и кратким разбором теории. Разбито на 4 части по 5 вопросов.

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

Вопросы 15 из 20

1Что создаёт выражение `squares = (x * x for x in xs)`?
AСписок — круглые скобки тоже создают список, просто без квадратных.
BКортеж — скобки вокруг выражения всегда дают кортеж, как в `(1, 2, 3)`.
CФункцию-генератор, аналог `def`-функции с `yield`, вызываемую позже.
DГенератор (`generator expression`), который выдаёт значения по одному при итерации.
Ответ: Генераторное выражение создаёт итератор с ленивыми вычислениями.

В отличие от list comprehension `[x * x for x in xs]`, генераторное выражение `(x * x for x in xs)` не вычисляет все значения сразу и не хранит их в списке. Оно возвращает объект генератора, который отдаёт элементы по мере запроса через `next()` или в цикле `for`.

2Есть `it = iter(['a', 'b'])`. Что вернёт вызов `next(it)`?
A`'b'`
B`'a'`
C`None`
DИсключение `StopIteration`.
Ответ: `next()` возвращает следующий элемент итератора и сдвигает его состояние.

После `it = iter(['a', 'b'])` первый `next(it)` вернёт `'a'`. Второй `next(it)` вернёт `'b'`, а следующий вызов уже приведёт к `StopIteration`.

3Что произойдёт при выполнении `it = iter([])` и затем `next(it)`?
AВернётся `None`.
BБудет выброшено исключение `StopIteration`.
CВернётся пустой список.
DБудет выброшено исключение `IndexError`.
Ответ: Когда элементов больше нет, `next()` сигнализирует конец итерации через `StopIteration`.

Итератор по пустому списку не содержит элементов. Первый же вызов `next(it)` не может вернуть значение и поднимает `StopIteration`. Именно это исключение использует цикл `for`, чтобы понять, что итерация завершилась.

4Есть функция `def f(x): print(x); return x`. Создали `g = (f(x) for x in [1, 2, 3])`. Сразу после создания `g` сколько раз выполнится `print(x)`?
A3 раза
B1 раз
C0 раз
DСразу будет выброшено исключение `StopIteration`.
Ответ: Generator expression не вызывает `f(x)` при создании; вызовы происходят при итерации.

Строка `g = (f(x) for x in [1, 2, 3])` создаёт объект генератора, но не запускает вычисление элементов. `f(x)` будет вызываться только когда вы начнёте читать из `g` — например, через `next(g)`, `list(g)` или цикл `for x in g`.

5Есть `xs = [1, 2, 3]` и `it = iter(xs)`. Сначала выполняется `a = list(it)`, а затем `b = list(it)`. Чему равно `b`?
A`[]`
B`[1, 2, 3]`
CБудет выброшено исключение `TypeError`.
DБудет выброшено исключение `StopIteration`.
Ответ: Итератор одноразовый: после полного прохода он исчерпан, повторная материализация даст пустой результат.

Вызов `list(it)` последовательно берёт элементы через `next(it)` до конца. Когда элементы заканчиваются, внутри используется `StopIteration`, но наружу исключение не пробрасывается. Итератор остаётся в состоянии «конец», поэтому второй `list(it)` возвращает пустой список.

1234

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

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

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

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

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