0

In python 3, imaging we have this dictionary, where a cardholder can have unlimited numbers of cards. So if I want to covert the following dictionary into a csv, the number of columns will be unlimited and not very readable.

[{"cardholder_a":"SUSPENDED","card_a":"SUSPENDED","card_b":"SUSPENDED",
"card_c":"SUSPENDED"}]

Ideally the csv should have the following columns and rows:

'cardholder','cardholder_status','card','card_status'
'cardholder_a','SUSPENDED','card_a','SUSPENDED'
'cardholder_a','SUSPENDED','card_b','SUSPENDED'
'cardholder_a','SUSPENDED','card_c','SUSPENDED'

and I am trying to restructure the dictionary into

[{"cardholder_a":"SUSPENDED","card_a""SUSPENDED"},{"cardholder_a":"SUSPENDED","card_b""SUSPENDED"},
{"cardholder_a":"SUSPENDED","card_c""SUSPENDED"}]

so that I can easily convert the dictionary into the csv like the format shown above

import csv
csv_columns = ['cardholder','cardholder_status','card','card_status']
dict_data = [{"cardholder_a":"SUSPENDED","card_a""SUSPENDED"},{"cardholder_a":"SUSPENDED","card_b""SUSPENDED"},
{"cardholder_a":"SUSPENDED","card_c""SUSPENDED"}]
csv_file = "Names.csv"
try:
    with open(csv_file, 'w') as csvfile:
        writer = csv.DictWriter(csvfile, fieldnames=csv_columns)
        writer.writeheader()
        for data in dict_data:
            writer.writerow(data)
except IOError:
    print("I/O error") 

Is there any easy way to convert the dictionaries above? Or any other better idea? Thank you!

Chubaka
  • 2,933
  • 7
  • 43
  • 58

1 Answers1

0

You didn't post any output from trial runs but when I ran your code I got:

Traceback (most recent call last):
  File "csv_out.py", line 11, in <module>
    writer.writerow(data)
  File "/usr/local/Cellar/python/3.7.4_1/Frameworks/Python.framework/Versions/3.7/lib/python3.7/csv.py", line 155, in writerow
    return self.writer.writerow(self._dict_to_list(rowdict))
  File "/usr/local/Cellar/python/3.7.4_1/Frameworks/Python.framework/Versions/3.7/lib/python3.7/csv.py", line 151, in _dict_to_list
    + ", ".join([repr(x) for x in wrong_fields]))

When I looked at the structure of data_dict I could see that you didn't have a key/value pair for each column. Restructure your data_dict like this:

dict_data = [
    {
        'cardholder': 'cardholder_a',
        'cardholder_status': 'SUSPENDED',
        'card': 'card_a',
        'card_status': 'SUSPENDED'
    },
    {
        'cardholder': 'cardholder_a',
        'cardholder_status': 'SUSPENDED',
        'card': 'card_b',
        'card_status': 'SUSPENDED'
    },
    {
        'cardholder': 'cardholder_a',
        'cardholder_status': 'SUSPENDED',
        'card': 'card_c',
        'card_status': 'SUSPENDED'
    }
]

Example output:

$ ~/code/sandbox $ python csv_out.py
$ ~/code/sandbox $ cat Names.csv
cardholder,cardholder_status,card,card_status
cardholder_a,SUSPENDED,card_a,SUSPENDED
cardholder_a,SUSPENDED,card_b,SUSPENDED
cardholder_a,SUSPENDED,card_c,SUSPENDED
currand60
  • 119
  • 8
  • Thank you @currand60! If there are unlimited cards for each cardholder, how can I convert the dictionary like you suggested? Any way to loop it over? – Chubaka Nov 25 '19 at 21:04
  • This will allow unlimited cards for each cardholder as long as you're ok with all the repetitive data. A better structure would be [{"cardholder": "cardholder_a", "cards": [{card_a_data}, {card_b_data}]. Then you could use something [like this](https://stackoverflow.com/questions/29400631/python-writing-nested-dictionary-to-csv). – currand60 Nov 25 '19 at 21:35