Trung Tran
Trung Tran

Reputation: 13721

Find maximum in list of objects in Python

I have a list of objects. Could someone help return the object with the highest score? For example:

objs = [
  {
    "name": "John",
    "score": 30
  },  
  {
    "name": "Josh",
    "score": 40
  },  
  {
    "name": "Jason",
    "score": 50
  },  
]

I need a method that will return the object with the highest score. In this case it should return

  {
    "name": "Jason",
    "score": 50
  }

So far I tried:

print max(objs, key=attrgetter('score'))

but it gives me AttributeError: 'dict' object has no attribute 'score'

Thanks in advance!

Upvotes: 0

Views: 2499

Answers (5)

akilat90
akilat90

Reputation: 5696

Pandas

You can convert the dictionary to a dataframe, find the index of the max score, extract the entry and convert that back to a dictionary.

This is probably faster when you have a large number of objects.

df = pd.DataFrame.from_dict(objs)
df.iloc[df['score'].idxmax(),:].to_dict()

Demo:

import pandas as pd

Reading to a dataframe

df = pd.DataFrame.from_dict(objs)

print(df)
    name  score
0   John     30
1   Josh     40
2  Jason     50

Locating the index of the maximum score

df.iloc[df['score'].idxmax(),:]

name     Jason
score       50
Name: 2, dtype: object

Extracting the max and writing to a dictionary

max_obj = df.iloc[df['score'].idxmax(),:].to_dict()
print(max_obj)
{'score': 50, 'name': 'Jason'}

Upvotes: 0

Ubdus Samad
Ubdus Samad

Reputation: 1215

This should do the job as well,

[a for a in objs if a["score"] == max([a["score"] for a in objs])]

Returns,

[{'score': 50, 'name': 'Jason'}]

Upvotes: 1

LFMekz
LFMekz

Reputation: 723

Not a Python expert and I guarantee there is a simpler and less verbose way to complete.

Though, it works for me:

for x in objs:
    hiscore = 0
    count = 0
    if x.get('score') > hiscore:
        hiscore = x.get('score')
        count += 1
print("Highest score is {data[score]} from player {data[name]}".format(data=x))

Upvotes: 0

ChipJust
ChipJust

Reputation: 1416

max(objs, key=lambda x: x['score'])

The key argument specifies a one-argument ordering function like that used for list.sort().

The most compact way to provide the function is with lambda.

>>> max(objs, key=lambda x: x['score'])
{'name': 'Jason', 'score': 50}

Upvotes: 2

Ignacio Vazquez-Abrams
Ignacio Vazquez-Abrams

Reputation: 798606

operator.attrgetter() is for attributes, e.g. foo.bar.

For item access you want operator.itemgetter() instead.

Upvotes: 4

Related Questions