0

Python noob here. I have the following in my database in an object called "data" and I want to write some python that will select the lowest score from each group of student_id....and grab the unique ObjectId for each minimum record found?

{u'student_id': 197, u'_id': ObjectId('50906d7fa3c412bb040eb88d'), u'type': u'homework', u'score': 10.90872422518918}
{u'student_id': 197, u'_id': ObjectId('50906d7fa3c412bb040eb88e'), u'type': u'homework', u'score': 88.3871242475841}
{u'student_id': 198, u'_id': ObjectId('50906d7fa3c412bb040eb892'), u'type': u'homework', u'score': 17.46279901047208}
{u'student_id': 198, u'_id': ObjectId('50906d7fa3c412bb040eb891'), u'type': u'homework', u'score': 76.18366499496366}
{u'student_id': 199, u'_id': ObjectId('50906d7fa3c412bb040eb895'), u'type': u'homework', u'score': 49.34223066136407}
{u'student_id': 199, u'_id': ObjectId('50906d7fa3c412bb040eb896'), u'type': u'homework', u'score': 58.09608083191365}

Thank you for your trouble....here is my code...

import pymongo

from itertools import groupby
from pymongo import Connection


connection = Connection('localhost', 27017)

db = connection.students

data = db.grades.find({'type' : 'homework'}).sort([('student_id',pymongo.ASCENDING),('score',pymongo.ASCENDING)])



for student_id, items in groupby(data, lambda s: s['student_id']):
    lowest_score = min(i['score'] for i in items)

    print lowest_score
2
  • so what part do you need help on? Can you narrow it down? Commented Nov 9, 2012 at 23:42
  • I can print out the lowest score per student but now I need to grab the unique ObjectId for each lowest_score. Commented Nov 9, 2012 at 23:46

2 Answers 2

2

I think you may be able to do your minimum check differently and get the ObjectID rather than the score from the minimum value. Here's how I'd do it:

lowest_id = min(items, key=lambda i: i['score'])['_id']

Now, it's possible (indeed, likely) that you can do something similar in the database itself, and probably that will have better performance. However, the above may work just fine if your data set is not too unwieldy.

Sign up to request clarification or add additional context in comments.

2 Comments

yep, I was about to answer that.. this is definitely the right way
yep...this one seems to be it.
1

not sure if you still have access to the student_id field, if so you could replace:

lowest_score = min(i['score'] for i in items)

with:

lowest_score = min((i['score'],i['student_id']) for i in items)

4 Comments

(min will compare the first element in each tuple)
ah...I just stumbled on this also...so then how would I say ...print or isolate the student_id at that point? (thank you again for your time)
student_id = lowest_score[1]
lowest_score = lowest_score[0], I probably should have renamed the tuple in the statement above

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.