Мы уже ознакомились с lambda-функциями и где они используются. Сейчас же исследуем вырванный из контекста реальный код и задания к нему.
def get_first_matching_object(predicate,objects=[]):
matching_objects = (obj for obj in objects if predicate(obj))
if matching_objects:
object = matching_objects[0]
return object
return None
print(get_first_matching_object(lambda x: x == 1, [2, 3, 4]))
▪️ Что не так с кодом ? Если мы запустим в таком виде, то получим
TypeError: 'generator' object is not subscriptable
. Это означает, что объект-генератор matching_objects
представляет собой итератор: он генерирует значения в том порядке, в котором они запрашиваются циклом for или вызовом next(matching_objects)
. Однако, дальше по коду пытаются получить доступ по индексу так, как будто это список или любой другой Sequence-тип, который позволяет получать доступ к произвольным k-м элементам через matching_objects[k]
. Если мы хотим, чтобы всё работало, нам нужно преобразовать в список list() или закрыть генератор в квадратные скобки: matching_objects = [obj for obj in objects if predicate(obj)]
▪️ Что код делает ? Есть некоторая функция, которая принимает в себя callback-функцию predicate и набор объектов (пустой по дефолту). Далее у нас как-то формируется список помеченных объектов, которые попадают в новый список только в том случае, если callback-функция возвращает для них
True
. Следующая конструкция говорит нам о том, что если полученный список matching_objects
не пустой, то мы выделяем первый входящий в него объект и возвращаем его. В противном случае возвращается None. Но последняя строчка не является обязательной. Потому что, в случае НЕсрабатывания условного оператора, у нас итак вернется None
.▪️ Что выведет на экран, если его исправить? Судя по тестовым параметрам, переданная lambda-функция ни на одном из элементов объекта
[2, 3, 4]
не вернет True. Поэтому список matching_objects
окажется пустым, в итоге нам вернется None. ▪️ Функция оптимизирована? Нет. Дело в том, что она перебирает все остальные элементы (тратит память и время выполнения), когда мы можем ограничиться рассмотрением первого подходящего. Тогда код можно исправить так:
def get_first_matching_object(predicate,objects=[]):
for obj in objects:
if predicate(obj):
return obj
return None
print(get_first_matching_object(lambda x: x == 1, [1, 2, 3, 4])) # 1
▪️ Какая сложность выполнения данной функции? В худшем случае: O(n) ; в лучшем случае : O(1).
#python #разработка #программирование #IT #алгоритмы
💡 Репетитор IT mentor // @mentor_it