23

Is there a better way of doing this? I don't really need the list to be sorted, just scanning through to get the item with the greatest specified attribute. I care most about readability but sorting a whole list to get one item seems a bit wasteful.

>>> import operator
>>> 
>>> a_list = [('Tom', 23), ('Dick', 45), ('Harry', 33)]
>>> sorted(a_list, key=operator.itemgetter(1), reverse=True)[0]
('Dick', 45)

I could do it quite verbosely...

>>> age = 0
>>> oldest = None
>>> for person in a_list:
...     if person[1] > age:
...             age = person[1]
...             oldest = person
... 
>>> oldest
('Dick', 45)

5 Answers 5

54
max(a_list, key=operator.itemgetter(1))
Sign up to request clarification or add additional context in comments.

2 Comments

Nice, didn't know that max had an optional key argument!
Ah, brilliant! Good python makes me happy.
8

You could use the max function.

Help on built-in function max in module __builtin__:

max(...)

max(iterable[, key=func]) -> value

max(a, b, c, ...[, key=func]) -> value

With a single iterable argument, return its largest item. With two or more arguments, return the largest argument.

max_item = max(a_list, key=operator.itemgetter(1))

Comments

5

The key can also be a lambda, for example:

people = [("Tom", 33), ("Dick", 55), ("Harry", 44)]
oldest = max(people, key=lambda p: p[1])

For some reason, using a lambda makes it feel more like "my code" is doing the work, compared with itemgetter. I think this feels particularly nice when you have a collection of objects:

class Person(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age

people = [Person("Tom", 33), Person("Dick", 55), Person("Harry", 44)]
oldest = max(people, key=lambda p: p.age)

Comments

2

Use the max() function or do it FP style:

reduce(lambda max, c: max if c <= max else c, [1, 6, 9, 2, 4, 0, 8, 1, 3])

Comments

0

Some people mentioned the following solution:

max(nameOfList, key=len)

However, this solution only returns the first sequential element of largest size. So, for example, in the case of list ["ABC","DCE"], only the first item of the list is returned.

To remedy this, I found the following workaround using the filter function:

filter((lambda x: len(x)==len(max(nameOfList, key=len))),nameOfList)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.