Работа функции filter с экземплярами класса

Есть класс Employee, от которого созданы несколько экземпляров.
Необходимо, используя функцию filter, получить список имен служащих, имеющих оценки ниже 5.

class Employee():
    def __init__(self, name, mark):
        self.name = name
        self.mark = mark

empl1 = Employee('Kate', 3)
empl2 = Employee('Lena', 4) 
empl3 = Employee('Natasha', 2)
empl4 = Employee('Liza', 1) 
empl5 = Employee('Vera', 5) 
empl6 = Employee('Valentina', 6)

my_list = [empl1, empl2, empl3, empl4, empl5, empl6] 

result = [filter(lambda el, el.mark < 5), my_list]

В списке result будут отобраны экземпляры класса, отвечающих заданному условию.
Вопрос. Можно ли модифицировать последнюю строку так, чтобы в списке оказались имена служащих?


Ответы (2 шт):

Автор решения: Jack_oS

Можно так:

class Employee():
    def __init__(self, name, mark):
        self.name = name
        self.mark = mark

empl1 = Employee('Kate', 3)
empl2 = Employee('Lena', 4) 
empl3 = Employee('Natasha', 2)
empl4 = Employee('Liza', 1) 
empl5 = Employee('Vera', 5) 
empl6 = Employee('Valentina', 6)

my_list = [empl1, empl2, empl3, empl4, empl5, empl6] 
result = [el.name for el in filter(lambda el: el.mark < 5, my_list)]

в результате:

>>> result
['Kate', 'Lena', 'Natasha', 'Liza']
→ Ссылка
Автор решения: insolor

filter только фильтрует. Если из каждого элемента нужно вытащить поле имени, то к каждому элементу уже отфильтрованной последовательности с помощью функции map нужно применить лямбду (или другую функцию), которая вытащит это поле:

result = list(map(lambda el: el.name, filter(lambda el: el.mark < 5, my_list)))

Или через attrgetter вместо лямбды:

from operator import attrgetter

result = list(map(attrgetter("name"), filter(lambda el: el.mark < 5, my_list)))

Вообще, если полностью переписать через list comprehension, в данном случае будет более компактно и читаемо:

result = [el.name for el in my_list if el.mark < 5]
→ Ссылка