1

I am trying to write a function that takes in a list of employee object and returns the object that corresponds to the employee with the youngest age. I am not sure why it is breaking. I know there are many ways to do this but I am particularly interested in solving it through the reduce tool

from functools import reduce as r
class Employee:
    bonus = 0
    def __init__(self,firstname,lastname,age,salary):
        self.fullname = firstname + " "+ lastnamestname
        self.email = "{}{}@outlook.com".format(firstname,lastname)
        self.age = age
        self.compensation = salary + self.bonus

e1 = Employee("Adam","George",33,100)
e2 = Employee("Samuel","Steans",35,133)
e3 = Employee("Laura","Nobel",25,200)
e4 = Employee("David","Chan",21,100)
e5 = Employee("Ben","Smith",80,90)
e6 = Employee("Santa","Ergory",19,120)
e7 = Employee("Tim","Smith",18,150)
e8 = Employee("Paul","Goodfellow",50,180)

employees = [e1,e2,e3,e4,e5,e6,e7,e8]

def getyoungest(emps):
    return r(lambda x,y:x.fullname if x.age < y.age else y.fullname,emps )

youngest = getyoungest(employees)
print(youngest)
2
  • You should always use a list comprehension instead of reduce, see artima.com/weblogs/viewpost.jsp?thread=98196 Commented Jan 1, 2020 at 21:28
  • 1
    @Boris that isn't what you link is stating. Reduce, in general, cannot be replaced with a list comprehension, list comprehensions replace filter/map operations, not reduce. What Guido mentions in that link is that he personally prefers to just see reduce replaced by a loop with the accumulation explicitly Commented Jan 1, 2020 at 22:24

3 Answers 3

4

For that you can use standard min function using the key parameter:

youngest = min(employees, key=lambda x:x.age)
Sign up to request clarification or add additional context in comments.

4 Comments

Alternatively, import operator and then min(employees, key=operator.attrgetter('age'))
@Boris: I know but I personally find that harder to read than lambda x:x.age
my comment was directed at the person asking. It might give them more flexibility, depending on what else they're trying to do. Also, I'm pretty sure operator is much faster.
@Boris: I beg to differ. May be your definition of "flexible" is different from mine but IMO attrgetter is way LESS flexible than a lambda where I can say for example key=lambda x:x.age + x.seniority*4. About speed let's just say that probably if you use Python (a good choice for many use cases) then speed for sure is not your main concern...
3

You need to return an object in the lambda, not a name. Right now, on the second comparison it will effectively try to access .age of the previously returned fullname, which will definitely break.

Comments

0

Probably easiest to change getyoungest to:

def getyoungest(emps):
    return r(lambda x,y:x if x.age < y.age else y, emps)

I.e. return the youngest Employee, not the name of the youngest Employee.

Then add

def __str__(self):
    return self.fullname


#> ./reduce_objects.py 
Tim Smith

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.