Home > OS >  Combine a list of multiple dictionaries into on single dict based on condition
Combine a list of multiple dictionaries into on single dict based on condition

Time:04-19

I want to merge some of the dictionaries, condition is whenever they have the same value in age and experience then I need to merge all the dict and keep the dict that doesn't below to this condition.

I have the following list of dictionaries:

lst = [
        {
            "Game": "Lego",
            "players": [         
            {
                "Age": "28",
                "Experience": "yes",
                "Score": [
                    {
                        "Alicia": 987
                    }
                ]
            },
                {
                    "Age": "20",
                    "Experience": "yes",
                    "Score": [
                        {
                            "Alex": 230
                        }
                    ]
                },
                {
                    "Age": "20",
                    "Experience": "yes",
                    "Score": [
                        {
                            "juana": 275
                        }
                    ]
                }
            ],
            "season": "summer"
        }
    ]

The output should look like this:

[
        {
            "Game": "Lego",
            "players": [
            {
                "Age": "28",
                "Experience": "yes",
                "Score": [
                    {
                        "Alicia": 987
                    }
                ]
            },         
                {
                    "Age": "20",
                    "Experience": "yes",
                    "Score": [
                        {
                            "Alex": 230
                        },
                        {
                            "juana": 275
                        }
                    ]
                }
            ],
            "season": "summer"
        }
    ]

I'm blocked in checking if the age/experience are equal after this step.

for d in lst:
        for i, sd in enumerate(d['players']):
            d['players'][i] = {k: v for k, v in d['players'][i].items()}

Note: i have multiple dict not only 2

CodePudding user response:

You could try this. Here I try to

1 convert the players list to dataframe 2 Then do a group by on the df to match for Age and experience and get Score. 3 Convert this dataframe back to dict, which is later updated to the original lst

import pandas as pd
lst = [] #Replace this with your list.
players = lst[0]['players']
print('Players before update\n', players)

df = pd.DataFrame.from_dict(players)
df_new = df.groupby(['Age','Experience'])['Score'].sum().reset_index()
players = df_new.to_dict('records')    
print('Players after update \n', players)    

print('lst before update\n', lst)
lst[0]['players'] = players
print('lst after update \n', lst)

Output:

Players before update
 [{'Age': '20', 'Experience': 'yes', 'Score': [{'Alex': 230}]}, {'Age': '20', 'Experience': 'yes', 'Score': [{'juana': 275}]}]
Players after update 
 [{'Age': '20', 'Experience': 'yes', 'Score': [{'Alex': 230}, {'juana': 275}]}]
lst before update
 [{'Game': 'Lego', 'players': [{'Age': '20', 'Experience': 'yes', 'Score': [{'Alex': 230}]}, {'Age': '20', 'Experience': 'yes', 'Score': [{'juana': 275}]}], 'season': 'summer'}]
lst after update 
 [{'Game': 'Lego', 'players': [{'Age': '20', 'Experience': 'yes', 'Score': [{'Alex': 230}, {'juana': 275}]}], 'season': 'summer'}]

CodePudding user response:

Note that this code is very messy and could be done much better, but I think it does the job:

    result_lst = []

for game_dict in lst:

    result_dict = {}
    result_dict['Game'] = game_dict['Game']
    result_dict['players'] = []
    result_dict['season'] = game_dict['season']

    for player_dict1 in game_dict['players']:

        starting_idx = game_dict['players'].index(player_dict1)   1

        for player_dict2 in game_dict['players'][starting_idx:]:

            if player_dict1['Age'] == player_dict2['Age'] and player_dict1['Experience'] == player_dict2['Experience']:

                age = player_dict1['Age']
                experience = player_dict1['Experience']

                for result_player in result_dict['players']:

                    if age == result_player['Age']:

                        if player_dict1['Score'][0] not in result_player['Score']:
                            result_player['Score'].append(player_dict1['Score'][0])

                        if player_dict2['Score'][0] not in result_player['Score']:
                            result_player['Score'].append(player_dict2['Score'][0])

                        break
                
                else:

                    players_dict = {'Age': age,
                                    'Experience': experience,
                                    'Score': [player_dict1['Score'][0],
                                            player_dict2['Score'][0],
                                    ]
                    }

                    result_dict['players'].append(players_dict)
    
    in_result_dict = True

    for player_dict in game_dict['players']:
        
        for result_players in result_dict['players']:
            for result_player in result_players['Score']:
                
                if player_dict['Score'][0] == result_player:
                    in_result_dict = False
                    break

        if in_result_dict:
            result_dict['players'].append(player_dict)

    result_lst.append(result_dict)


print(result_lst)

Also note that this way of storing information is too redundant and makes it hard to access the data and iterate over it, please consider refactoring it.

Anyway, the output is:

[{'Game': 'Lego', 
'players': [{'Age': '20', 
            'Experience': 'yes', 
            'Score': [{'Alex': 230}, {'juana': 275}]}, 
            
            {'Age': '28', 
                'Experience': 'yes', 
                'Score': [{'Alicia': 987}]}], 
'season': 'summer'}]
  • Related