Как получить следующий элемент итератора в Python
Что проверяют
Java-разработчику этот вопрос задают, чтобы понять, видите ли вы общий паттерн «Итератор» за синтаксисом конкретного языка. Поэтому сильный ответ сразу сравнивает Python с java.util.Iterator, а уточнение обычно звучит так: почему в Python нет hasNext().
Как отвечать
В Python следующий элемент берут встроенной функцией next(it), а сам итератор получают через iter(collection). Это прямые аналоги collection.iterator() и it.next() в Java.
Главное различие в том, как сообщается конец:
- Java: сначала
hasNext(), потомnext(). Вызовnext()без элементов бросаетNoSuchElementException, но в нормальном коде до этого не доходит; - Python: метода «есть ли ещё» нет. Вы просто вызываете
next(), а на исчерпанном итераторе он бросаетStopIteration. Это стиль EAFP: проще попробовать и поймать исключение, чем проверять заранее. ЦиклforобрабатываетStopIterationсам; - значение по умолчанию:
next(it, None)вернётNoneвместо исключения, в Java ближе всего связкаit.hasNext() ? it.next() : null; - свой итератор: в Java вы реализуете
Iterator<T>иIterable<T>, в Python методы__iter__и__next__, а чаще пишете генератор сyield, у которого в Java прямого аналога нет; - одноразовость: и там и там итератор проходится один раз, для второго прохода нужен новый.
Упомяните изменение коллекции во время обхода. Итераторы ArrayList и HashMap работают по принципу fail-fast и бросают ConcurrentModificationException. В Python изменение размера словаря во время обхода даёт RuntimeError, а список молча пропускает элементы.
Где спотыкаются
Переносят Java-привычку в Python: ищут hasNext() или пишут while True с ручной обработкой StopIteration вместо обычного for.
Путают итерируемый объект с итератором. next(my_list) в Python падает с TypeError, так же как в Java нельзя вызвать next() у самого List.
Считают StopIteration ошибкой, которую нужно логировать. Это штатный сигнал конца, а не сбой, и ловить его стоит только там, где вы вызываете next() вручную.