Chris
Chris

Reputation: 1672

How to merge lists of dictionaries

With lists of dictionaries such as the following:

user_course_score = [
    {'course_id': 1456, 'score': 56}, 
    {'course_id': 316, 'score': 71}
]
courses = [
    {'course_id': 1456, 'name': 'History'}, 
    {'course_id': 316, 'name': 'Science'}, 
    {'course_id': 926, 'name': 'Geography'}
]

What is the best way to combine them into the following list of dictionaries:

user_course_information = [
    {'course_id': 1456, 'score': 56, 'name': 'History'}, 
    {'course_id': 316, 'score': 71, 'name': 'Science'}, 
    {'course_id': 926, 'name': 'Geography'} # Note: the student did not take this test
]

Or would it be better to store the data differently, such as:

courses = {
    '1456': 'History',
    '316': 'Science',
    '926': 'Geography'
}

Thanks for your help.

Upvotes: 13

Views: 8756

Answers (4)

Adam
Adam

Reputation: 2180

Here's a possible solution:

def merge_lists(l1, l2, key):
    merged = {}
    for item in l1+l2:
        if item[key] in merged:
            merged[item[key]].update(item)
        else:
            merged[item[key]] = item
    return merged.values()

courses = merge_lists(user_course_score, courses, 'course_id')

Produces:

[{'course_id': 1456, 'name': 'History', 'score': 56},
 {'course_id': 316, 'name': 'Science', 'score': 71},
 {'course_id': 926, 'name': 'Geography'}]

As you can see, I used a dictionary ('merged') as a halfway point. Of course, you can skip a step by storing your data differently, but it depends also on the other uses you may have for those variables.

All the best.

Upvotes: 24

David Lemphers
David Lemphers

Reputation: 3628

You could also try:

[
    course.update(score) for course 
    in courses for score in user_course_score 
    if course['course_id'] == score['course_id']
]

:)

Upvotes: 1

Katriel
Katriel

Reputation: 123622

Rahul is correct; a list of dictionaries is not the right way to do this. Think about it like this: dictionaries are mappings between pieces of data. Your final example, courses, is the right way to store the data; you could then do something like this to store the per-user data:

courses = {
    1456: 'History',
    316: 'Science',
    926: 'Geography'
} # Note the lack of quotes

test_scores = {
    1456: { <user-id>: <score on History test> },
    316: { <user-id>: <score on History test> },
    926: { <user-id>: <score on History test> }
}

Upvotes: 2

Rahul
Rahul

Reputation: 1876

dictionary is basically a list of (key, value) pairs.

in your case,

user_course_score can just be a dictionary of (course_id, score) rather than a list of dictionaries (you are just complicating it unnecessarily)

similarly, course can just be a dictionary of (course_id, name)

what you have suggested in the end is the right way :)

Upvotes: 3

Related Questions