Этот вариант логически работает: matching_objects — список, поэтому индексирование корректно. Недостаток — проверяются все элементы и создаётся лишний список; первый результат можно найти лениво.
Код‑ревью: выявление дефектов в функции get_first_matching_object
Этот вариант логически работает: matching_objects — список, поэтому индексирование корректно. Недостаток — проверяются все элементы и создаётся лишний список; первый результат можно найти лениво.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Выполните ревизию представленного кода функции. Обнаружьте и перечислите все логические и технические ошибки. Функция предназначена для возврата первого элемента из переданного списка, который удовлетворяет заданному предикату.
def get_first_matching_object(predicate, objects=[]):
matching_objects = [obj for obj in objects if predicate(obj)]
if matching_objects:
return matching_objects[0]
else:
return None
Ответ
Этот вариант логически работает: matching_objects — список, поэтому индексирование корректно. Недостаток — проверяются все элементы и создаётся лишний список; первый результат можно найти лениво.
В отличие от генераторного варианта, здесь нет ошибки truthiness или индексирования. Улучшение:
def get_first_matching_object(predicate, objects=()):
return next((obj for obj in objects if predicate(obj)), None)
После первого совпадения обход прекращается. Изменяемый default-список в исходнике не мутируется, поэтому сам по себе ещё не вызывает накопления элементов; кортеж просто безопаснее для дальнейшего сопровождения. Если predicate имеет побочные эффекты, раннее прекращение меняет число его вызовов — такой контракт нужно учитывать.