Search code examples
pythonlistdictionarylist-comprehensiondictionary-comprehension

simpler way for getting data from dictionary


I have a dictionary: The last entry of a tuple are the minutes when the goals were shot. For example: Oscar a Brazilian player shot a goal in the 90th minute

players = {
    "Brazil": [
        (12, "Júlio César", "Goalkeeper", []),
        (4, "David Luiz", "Defender", []),
        (6, "Marcelo", "Defender", []),
        (13, "Dante", "Defender", []),
        (23, "Maicon", "Defender", []),
        (5, "Fernandinho", "Midfielder", []),
        (7, "Hulk", "Midfielder", []),
        (8, "Paulinho", "Midfielder", []),
        (11, "Oscar", "Midfielder", [90]),
        (16, "Ramires", "Midfielder", []),
        (17, "Luiz Gustavo", "Midfielder", []),
        (19, "Willian", "Midfielder", []),
        (9, "Fred", "Striker", []),
    ],
    "Germany": [
        (1, "Manuel Neuer", "Goalkeeper", []),
        (4, "Benedikt Höwedes", "Defender", []),
        (5, "Mats Hummels", "Defender", []),
        (16, "Philipp Lahm", "Defender", []),
        (17, "Per Mertesacker", "Defender", []),
        (20, "Jérôme Boateng", "Defender", []),
        (6, "Sami Khedira", "Midfielder", [29]),
        (7, "Bastian Schweinsteiger", "Midfielder", []),
        (8, "Mesut Özil", "Midfielder", []),
        (13, "Thomas Müller", "Midfielder", [11]),
        (14, "Julian Draxler", "Midfielder", []),
        (18, "Toni Kroos", "Midfielder", [24, 26]),
        (9, "André Schürrle", "Striker", [69, 79]),
        (11, "Miroslav Klose", "Striker", [23]),
    ],
}

I want to create a function that takes the team and a minute as input and returns the number of goals that were shot to that minute. I tried it like this:

def score_at_minute(team,minute):
    global players
    goals = [goals for (number, player, position, goals) in players[team] if len(goals)>=1]
    goals_1 = [goal[0] for goal in goals if len(goal)>=1 if goal[0] <= minute]
    goals_2 = [goal[1] for goal in goals if len(goal) ==2 if goal[1]<= minute]
    all_goals = goals_1+goals_2
    return len(all_goals)

My function call looks like this:

score_at_minute("Germany",90)

Is there a simpler way or in the best way a one liner?


Solution

  • How about this -

    def score_at_minute(x,y):
        return len([j for i in players.get(x) for j in i[3] if j<=y])
    
    score_at_minute("Germany",25)
    
    3
    

    Another version -

    score_at_minute = lambda x,y: len([j for i in players.get(x) for j in i[3] if j<=y])
    
    score_at_minute('Germany', 90)
    
    7
    

    How this works -

    1. players.get(x) fetches the list of players and goals under the country x
    2. i[3] is the item that holds the list of goals
    3. When iterating over this, you will end up with a list of lists, where each sublist contains goals. [[],[],[],[24],[32,45]] .. etc.
    4. You can now flatten the list of lists by using [item for sublist in list for item in sublist]
    5. Then you can apply the filter over this list (less than equal to the input minutes)
    6. Finally calculate the length.