PGS
PGS

Reputation: 1194

Iterate dict of dict in python efficiently/pythonic

I have a dict of dict with List of tuples in it. Have to iterate and update in another dictonary. For example:

input_dict = {'503334': {'InterRAT': [
                            ['10', 'PLMN-1', 'SIB'],
                            ['20', 'PLMN-2', 'SIB']],
                        'Intra': [
                            ['30', 'PLMN-1', 'SIB'],
                            ['40', 'PLMN-2', 'SIB']],
                        'Inter': [
                            ['50', 'PLMN-2', 'SIB'],
                            ['60', 'PLMN-1', 'SIB']]},
              '490847': {'InterRAT': [
                            ['10', 'PLMN-1', 'SIB'],
                            ['80', 'PLMN-2', 'SIB']],
                        'Intra': [
                            ['20', 'PLMN-1', 'SIB'],
                            ['30', 'PLMN-2', 'SIB']],
                        'Inter': [
                            ['50', 'PLMN-2', 'SIB'],
                            ['60', 'PLMN-1', 'SIB']]}}

Expected is: ( Iterate the dict and take first item in the list of tuples and put in List)

{'503334': {'InterRAT': ['10', '20'], 
            'Intra': ['30', '40'], 
            'Inter': ['50', '60']}, 
 '490847': {'InterRAT': ['10', '80'],
            'Intra': ['20', '30'], 
            'Inter': ['50', '60']}}

Below is my code,

for key, attrs in input_dict.items():
    for type, attr_list in attrs.items():
        try:
            if type == 'Inter':
                output[key]['Inter'] = \
                    [nbr[0] for nbr in attr_list]
            elif type == 'Intra':
                output[key]['Intra'] = \
                    [nbr[0] for nbr in attr_list]
            else:
                output[key]['InterRAT'] = \
                    [nbr[0] for nbr in attr_list]
        except KeyError as e:
            print("Exception {}".format(e))
            continue

Is there any efficient or pythonic way to do this.

Upvotes: 0

Views: 74

Answers (1)

norok2
norok2

Reputation: 26956

If you want to modify the input_dict in-place you can do something like this:

for k1, v1 in input_dict.items():
    for k2, v2 in v1.items():
        v1[k2] = [l[0] for l in v2]

print(input_dict)
# {'503334': {'InterRAT': ['10', '20'], 'Intra': ['30', '40'], 'Inter': ['50', '60']}, '490847': {'InterRAT': ['10', '80'], 'Intra': ['20', '30'], 'Inter': ['50', '60']}}

If you want to create a new object, you do similarly but you assign to the new object:

output = {}
for k1, v1 in input_dict.items():
    output[k1] = {}
    for k2, v2 in v1.items():
        output[k1][k2] = [l[0] for l in v2]

print(output)
# {'503334': {'InterRAT': ['10', '20'], 'Intra': ['30', '40'], 'Inter': ['50', '60']}, '490847': {'InterRAT': ['10', '80'], 'Intra': ['20', '30'], 'Inter': ['50', '60']}}

This can be written in a single statement using comprehensions:

output = {
    k1: {k2: [l[0] for l in v2] for k2, v2 in v1.items()}
    for k1, v1 in input_dict.items()}

Aside of avoiding the unnecessary try/except and the if/elif/else block, this is close to your code. This is a far Pythonic as it could get, I think.

Upvotes: 1

Related Questions