Home > Software design >  creat a new dictionary to summarize the original dictionary using loops
creat a new dictionary to summarize the original dictionary using loops

Time:10-27

The dataset or say the given dictionary is:

# A list of video reviews
# - Each review has the name of the video, the numer of views
#   and a list of user reviews.
# - Each user review has the user's name and the review they gave
#   to the video.

video_reviews = [
    {
        "name": "Cats doing nothing",
        "number_of_views": 450743,
        "reviews": [
            {"name": "Jeb", "review": 5},
            {"name": "Samantha", "review": 2},
            {"name": "Crystal", "review": 3},
        ]
    },
    {
        "name": "All Fail",
        "number_of_views": 1239734,
        "reviews": [
            {"name": "Crystal", "review": 5},
            {"name": "Frank", "review": 3},
            {"name": "Jeb", "review": 3},
        ]
    },
    {
        "name": "Runaway Nintendo",
        "number_of_views": 48343,
        "reviews": [
            {"name": "Samantha", "review": 4},
            {"name": "Bill", "review": 3},
            {"name": "Sarah", "review": 4},
        ]
    },
]

heres my problem: I want to define a function and create a user summary - a dictionary - where the keys are the name of the user and the value is a list of the videos that they have reviewed. The result is expected to be like this:

{
    "Jeb": ["Cats doing nothing", "All Fail"],
    "Samantha": ["Cats doing nothing","Runaway Nintendo"],
    "Crystal": ["Cats doing nothing", "All Fail"],
    "Frank": ["All Fail"],
    "Bill": ["Runaway Nintendo"],
    "Sarah": ["Runaway Nintendo"],
}

Currently, my code is:

def create_user_summary(video_reviews):
    summary = {}
    for video in video_reviews:
        for person in video["reviews"]:
            user = person["name"]
            video_name = []
            if person["name"] == user:
                video_name.append(video["name"])
                summary[user] = video_name
    return summary
AssertionError: 
You returned:
    {'Jeb': ['All Fail'], 'Samantha': ['Runaway Nintendo'], 'Crystal': ['All Fail'], 'Frank': ['All Fail'], 'Bill': ['Runaway Nintendo'], 'Sarah': ['Runaway Nintendo']}
instead of:
    {'Jeb': ['Cats doing nothing', 'All Fail'], 'Samantha': ['Cats doing nothing', 'Runaway Nintendo'], 'Crystal': ['Cats doing nothing', 'All Fail'], 'Frank': ['All Fail'], 'Bill': ['Runaway Nintendo'], 'Sarah': ['Runaway Nintendo']}

How do I revise my code and let the output match the expected one?

CodePudding user response:

Here's a modified version of your code that I think gives you what you want:

def create_user_summary(video_reviews):
    summary = {}
    for video in video_reviews:
        for person in video["reviews"]:
            summary.setdefault(person["name"], []).append(video["name"])
    return summary

Result"

{'Jeb': ['Cats doing nothing', 'All Fail'], 'Samantha': ['Cats doing nothing', 'Runaway Nintendo'], 'Crystal': ['Cats doing nothing', 'All Fail'], 'Frank': ['All Fail'], 'Bill': ['Runaway Nintendo'], 'Sarah': ['Runaway Nintendo']}

CodePudding user response:

You can use some python built-in functions for this, like sorted and groupby and glue it all together with list and dict comprehensions:

from itertools import groupby
source = ((rev['name'], vid['name']) for vid in video_reviews for rev in vid['reviews'])
result = {k: list(m for _, m in g) for k, g in groupby(sorted(source), lambda x: x[0])}
print(result)
  • Related