Home > Back-end >  Check if nested dictionary key same as item in list
Check if nested dictionary key same as item in list

Time:09-21

This might be a super easy question for most, but a struggling student would appreciate some help. I have a dictionary with a list of nested dictionaries. Some of the items are missing or in the wrong order.

I'm trying to export it so csv in a specific order (list) I need to compare if items in the list key names and return the values. If the key doesn't exist to return 'N/A'

Sample

my_list=["_id", "count", "f_name", "l_name", "number", "country]

my_dict = [{
    "_id": 123,
    "count": 345,
    "account": [
        {
            "f_name": "Adam",
            "l_name": "Adamson",
            "number": 1,
            "country": "Argentina"
        },
        {,
            "l_name": "Charlson",
            "country": "Canada"

        },
        {
            "f_name": "David",
            "country": "Denmark",
            "number": 3,
            "l_name": "Davidson"
        },
    ]
},
{
    "_id": 678,
    "count": 981,
    "account": [
        {
            "f_name": "Edvin",
            "number": 4,
            "country": "Equador"
        },      
    ]
}]

Expected Output

_id   | count | f_name | l_name   | number | country
------------------------------------------------------
123   | 345   | Adam   | Adamson  |   1    | Argentina
------------------------------------------------------
123   | 345   | N/A    | Charlosn |  N/A   | Canada
------------------------------------------------------
123   | 345   | David  | Davidson |   3    | Denmark
------------------------------------------------------
678   | 981   | Edwin  | N/A      |   4    | Equador
------------------------------------------------------


Any help or advice would be appreciated.

CodePudding user response:

You can implement a loop like this one.

fmtstr = "{:<4} | {:<6} | {:<8} | {:<8} | {:^6} | {:<8}"
line = "--------------------------------------------------------"

print(fmtstr.format(*my_list))
print(line)

for entry in my_dict:
    id_ = entry.get('_id')
    count = entry.get('count')
    for nentry in entry.get('account', []):
        print(fmtstr.format(id_,
                            count,
                            nentry.get('f_name', 'N/A'),
                            nentry.get('l_name', 'N/A'),
                            nentry.get('number', 'N/A'),
                            nentry.get('country', 'N/A')))
        print(line)

Using your data, the output is:

_id  | count  | f_name   | l_name   | number | country 
--------------------------------------------------------
123  | 345    | Adam     | Adamson  |   1    | Argentina
--------------------------------------------------------
123  | 345    | N/A      | Charlson |  N/A   | Canada  
--------------------------------------------------------
123  | 345    | David    | Davidson |   3    | Denmark 
--------------------------------------------------------
678  | 981    | Edvin    | N/A      |   4    | Equador
--------------------------------------------------------

If you need the data in CSV format the solution is simpler:

print(','.join(my_list))

for entry in my_dict:
    id_ = entry.get('_id')
    count = entry.get('count')
    for nentry in entry.get('account', []):
        print(("{},{},{},{},{},{}"
               .format(id_,
                       count,
                       nentry.get('f_name', 'N/A'),
                       nentry.get('l_name', 'N/A'),
                       nentry.get('number', 'N/A'),
                       nentry.get('country', 'N/A'))))

This time the output will be:

_id,count,f_name,l_name,number,country
123,345,Adam,Adamson,1,Argentina
123,345,N/A,Charlson,N/A,Canada
123,345,David,Davidson,3,Denmark
678,981,Edvin,N/A,4,Equador

CodePudding user response:

Once you fix the typos in your list and dictionary, you can convert the dictionary to a table (list of lists) and export it using the csv module:

table = [ [d.get(k,a.get(k,'N/A')) for k in my_list] 
          for d in my_dict for a in d['account'] ]

Output:

for row in table:print(row)

[123, 345, 'Adam', 'Adamson', 1, 'Argentina']
[123, 345, 'N/A', 'Charlson', 'N/A', 'Canada']
[123, 345, 'David', 'Davidson', 3, 'Denmark']
[678, 981, 'Edvin', 'N/A', 4, 'Equador']

Then save to a csv file:

import csv
with open('table.csv','w') as f:
    output = csv.writer(f)
    output.writerow(my_list)
    for row in table: 
        output.writerow(row)

Of pretty print the table:

for row in [my_list,*table]:
    print("|".join(f" {str(c):10}" for c in row))
    print("-"*70)

 _id       | count     | f_name    | l_name    | number    | country   
----------------------------------------------------------------------
 123       | 345       | Adam      | Adamson   | 1         | Argentina 
----------------------------------------------------------------------
 123       | 345       | N/A       | Charlson  | N/A       | Canada    
----------------------------------------------------------------------
 123       | 345       | David     | Davidson  | 3         | Denmark   
----------------------------------------------------------------------
 678       | 981       | Edvin     | N/A       | 4         | Equador   
----------------------------------------------------------------------
  • Related