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
----------------------------------------------------------------------