Python Forum
trying to write a dictionary in a csv file
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
trying to write a dictionary in a csv file
#1
I'm trying to write the dictionary straightlist in a csv file like this

Rank , Hand
1,[['10', 'X'], ['11', 'X'], ['12', 'X'], ['13', 'X'], ['14', 'X']]
2,[['9', 'X'], ['10', 'X'], ['11', 'X'], ['12', 'X'], ['13', 'X']]
3,[['8', 'X'], ['9', 'X'], ['10', 'X'], ['11', 'X'], ['12', 'X']]
...

import csv
filename = 'rankedhands.csv'
fields = ['Rank','Hands']

straightlist =
{
    1: [['10', 'X'], ['11', 'X'], ['12', 'X'], ['13', 'X'], ['14', 'X']],
    2: [['9', 'X'], ['10', 'X'], ['11', 'X'], ['12', 'X'], ['13', 'X']],
    3: [['8', 'X'], ['9', 'X'], ['10', 'X'], ['11', 'X'], ['12', 'X']],
    4: [['7', 'X'], ['8', 'X'], ['9', 'X'], ['10', 'X'], ['11', 'X']],
    5: [['6', 'X'], ['7', 'X'], ['8', 'X'], ['9', 'X'], ['10', 'X']],
    6: [['5', 'X'], ['6', 'X'], ['7', 'X'], ['8', 'X'], ['9', 'X']],
    7: [['4', 'X'], ['5', 'X'], ['6', 'X'], ['7', 'X'], ['8', 'X']],
    8: [['3', 'X'], ['4', 'X'], ['5', 'X'], ['6', 'X'], ['7', 'X']],
    9: [['2', 'X'], ['3', 'X'], ['4', 'X'], ['5', 'X'], ['6', 'X']]
 }

with open(filename, 'w') as csvfile:
    csvwriter = csv.DictWriter(csvfile, fieldnames = fields)
    csvwriter.writeheader()
    csvwriter.writerows(straightlist)
but i get this error:

Error:
Traceback (most recent call last): File "/usr/lib/python3.8/idlelib/run.py", line 559, in runcode exec(code, self.locals) File "/home/fook/Documents/pygame/Poker Practice/test.py", line 228, in <module> csvwriter.writerows(straightlist) File "/usr/lib/python3.8/csv.py", line 157, in writerows return self.writer.writerows(map(self._dict_to_list, rowdicts)) File "/usr/lib/python3.8/csv.py", line 147, in _dict_to_list wrong_fields = rowdict.keys() - self.fieldnames AttributeError: 'int' object has no attribute 'keys'
can you help me please
Reply
#2
Your dictionary does not have any keys named "Rank" or "Hands". Your field names are 1, 2, 3,...9, not "Rank" and "Hands".

DictWriter.writerows(straightlist) expects straightlist to be an iterable that returns dictionaries.

This works:
import csv
filename = 'rankedhands.csv'

straightlist = {
    1: [['10', 'X'], ['11', 'X'], ['12', 'X'], ['13', 'X'], ['14', 'X']],
    2: [['9', 'X'], ['10', 'X'], ['11', 'X'], ['12', 'X'], ['13', 'X']],
    3: [['8', 'X'], ['9', 'X'], ['10', 'X'], ['11', 'X'], ['12', 'X']],
    4: [['7', 'X'], ['8', 'X'], ['9', 'X'], ['10', 'X'], ['11', 'X']],
    5: [['6', 'X'], ['7', 'X'], ['8', 'X'], ['9', 'X'], ['10', 'X']],
    6: [['5', 'X'], ['6', 'X'], ['7', 'X'], ['8', 'X'], ['9', 'X']],
    7: [['4', 'X'], ['5', 'X'], ['6', 'X'], ['7', 'X'], ['8', 'X']],
    8: [['3', 'X'], ['4', 'X'], ['5', 'X'], ['6', 'X'], ['7', 'X']],
    9: [['2', 'X'], ['3', 'X'], ['4', 'X'], ['5', 'X'], ['6', 'X']]
 }

x = [{'Rank':key, "Hands":value} for key, value in straightlist.items()]  # Make a list of dictionaries
with open(filename, 'w') as csvfile:
    csvwriter = csv.DictWriter(csvfile, fieldnames = ["Rank", "Hands"])
    csvwriter.writeheader()
    csvwriter.writerows(x)
It produces output like this:
Output:
Rank,Hands 1,"[['10', 'X'], ['11', 'X'], ['12', 'X'], ['13', 'X'], ['14', 'X']]" 2,"[['9', 'X'], ['10', 'X'], ['11', 'X'], ['12', 'X'], ['13', 'X']]" 3,"[['8', 'X'], ['9', 'X'], ['10', 'X'], ['11', 'X'], ['12', 'X']]" 4,"[['7', 'X'], ['8', 'X'], ['9', 'X'], ['10', 'X'], ['11', 'X']]" 5,"[['6', 'X'], ['7', 'X'], ['8', 'X'], ['9', 'X'], ['10', 'X']]" 6,"[['5', 'X'], ['6', 'X'], ['7', 'X'], ['8', 'X'], ['9', 'X']]" 7,"[['4', 'X'], ['5', 'X'], ['6', 'X'], ['7', 'X'], ['8', 'X']]" 8,"[['3', 'X'], ['4', 'X'], ['5', 'X'], ['6', 'X'], ['7', 'X']]" 9,"[['2', 'X'], ['3', 'X'], ['4', 'X'], ['5', 'X'], ['6', 'X']]"
This also works:
with open(filename, 'w') as csvfile:
    csvwriter = csv.writer(csvfile)
    csvwriter.writerows(straightlist.items())
It produces the same output sans header..
Output:
1,"[['10', 'X'], ['11', 'X'], ['12', 'X'], ['13', 'X'], ['14', 'X']]" 2,"[['9', 'X'], ['10', 'X'], ['11', 'X'], ['12', 'X'], ['13', 'X']]" 3,"[['8', 'X'], ['9', 'X'], ['10', 'X'], ['11', 'X'], ['12', 'X']]" 4,"[['7', 'X'], ['8', 'X'], ['9', 'X'], ['10', 'X'], ['11', 'X']]" 5,"[['6', 'X'], ['7', 'X'], ['8', 'X'], ['9', 'X'], ['10', 'X']]" 6,"[['5', 'X'], ['6', 'X'], ['7', 'X'], ['8', 'X'], ['9', 'X']]" 7,"[['4', 'X'], ['5', 'X'], ['6', 'X'], ['7', 'X'], ['8', 'X']]" 8,"[['3', 'X'], ['4', 'X'], ['5', 'X'], ['6', 'X'], ['7', 'X']]" 9,"[['2', 'X'], ['3', 'X'], ['4', 'X'], ['5', 'X'], ['6', 'X']]"
Reply
#3
This might be what you really want.
filename = 'rankedhands.csv'

straightlist = {
    1: [['10', 'X'], ['11', 'X'], ['12', 'X'], ['13', 'X'], ['14', 'X']],
    2: [['9', 'X'], ['10', 'X'], ['11', 'X'], ['12', 'X'], ['13', 'X']],
    3: [['8', 'X'], ['9', 'X'], ['10', 'X'], ['11', 'X'], ['12', 'X']],
    4: [['7', 'X'], ['8', 'X'], ['9', 'X'], ['10', 'X'], ['11', 'X']],
    5: [['6', 'X'], ['7', 'X'], ['8', 'X'], ['9', 'X'], ['10', 'X']],
    6: [['5', 'X'], ['6', 'X'], ['7', 'X'], ['8', 'X'], ['9', 'X']],
    7: [['4', 'X'], ['5', 'X'], ['6', 'X'], ['7', 'X'], ['8', 'X']],
    8: [['3', 'X'], ['4', 'X'], ['5', 'X'], ['6', 'X'], ['7', 'X']],
    9: [['2', 'X'], ['3', 'X'], ['4', 'X'], ['5', 'X'], ['6', 'X']]
 }

with open(filename, 'w') as csvfile:
    csvwriter = csv.DictWriter(csvfile, fieldnames = range(1,10))
    csvwriter.writeheader()
    csvwriter.writerow(straightlist)  # Only 1 dictionary, so only 1 row
And this outputs:
Output:
1,2,3,4,5,6,7,8,9 "[['10', 'X'], ['11', 'X'], ['12', 'X'], ['13', 'X'], ['14', 'X']]","[['9', 'X'], ['10', 'X'], ['11', 'X'], ['12', 'X'], ['13', 'X']]","[['8', 'X'], ['9', 'X'], ['10', 'X'], ['11', 'X'], ['12', 'X']]","[['7', 'X'], ['8', 'X'], ['9', 'X'], ['10', 'X'], ['11', 'X']]","[['6', 'X'], ['7', 'X'], ['8', 'X'], ['9', 'X'], ['10', 'X']]","[['5', 'X'], ['6', 'X'], ['7', 'X'], ['8', 'X'], ['9', 'X']]","[['4', 'X'], ['5', 'X'], ['6', 'X'], ['7', 'X'], ['8', 'X']]","[['3', 'X'], ['4', 'X'], ['5', 'X'], ['6', 'X'], ['7', 'X']]","[['2', 'X'], ['3', 'X'], ['4', 'X'], ['5', 'X'], ['6', 'X']]"
Reply
#4
oh so you need a list of dictionaries...
but it still gives me this error and i can't figure it out?

Error:
Traceback (most recent call last): File "/usr/lib/python3.8/idlelib/run.py", line 559, in runcode exec(code, self.locals) File "/home/fook/Documents/pygame/Poker Practice/test.py", line 246, in <module> csvwriter.writerows(csvwriter.writerows(straightlist.items())) File "/usr/lib/python3.8/csv.py", line 157, in writerows return self.writer.writerows(map(self._dict_to_list, rowdicts)) File "/usr/lib/python3.8/csv.py", line 147, in _dict_to_list wrong_fields = rowdict.keys() - self.fieldnames AttributeError: 'tuple' object has no attribute 'keys'
Reply
#5
I would save the dictionary to a json file.

The example below includes a test routine and dictionary display routine which you don't need for your app.

import csv
import os
import json


filename = 'rankedhands.json'

def save_rankedhands():
    # Make sure cwd same as script
    os.chdir(os.path.abspath(os.path.dirname(__file__)))

    fields = ['Rank','Hands']

    straightlist = {
        1: [['10', 'X'], ['11', 'X'], ['12', 'X'], ['13', 'X'], ['14', 'X']],
        2: [['9', 'X'], ['10', 'X'], ['11', 'X'], ['12', 'X'], ['13', 'X']],
        3: [['8', 'X'], ['9', 'X'], ['10', 'X'], ['11', 'X'], ['12', 'X']],
        4: [['7', 'X'], ['8', 'X'], ['9', 'X'], ['10', 'X'], ['11', 'X']],
        5: [['6', 'X'], ['7', 'X'], ['8', 'X'], ['9', 'X'], ['10', 'X']],
        6: [['5', 'X'], ['6', 'X'], ['7', 'X'], ['8', 'X'], ['9', 'X']],
        7: [['4', 'X'], ['5', 'X'], ['6', 'X'], ['7', 'X'], ['8', 'X']],
        8: [['3', 'X'], ['4', 'X'], ['5', 'X'], ['6', 'X'], ['7', 'X']],
        9: [['2', 'X'], ['3', 'X'], ['4', 'X'], ['5', 'X'], ['6', 'X']]
    }

    with open(filename, 'w') as jfile:
        json.dump(straightlist, jfile)

def display_dict(dictname, level=0):
    indent = " " * (4 * level)
    for key, value in dictname.items():
        if isinstance(value, dict):
            print(f'\n{indent}{key}')
            level += 1
            display_dict(value, level)
        else:
            print(f'{indent}{key}: {value}')
        if level > 0:
            level -= 1

def test_save_rankedhands():
    # Save dictionary to json file
    save_rankedhands()

    # read json file into newdict and display
    with open(filename) as jfile:
        newdict = json.load(jfile)

    display_dict(newdict)


if __name__ == '__main__':
    test_save_rankedhands()
Test results:
Output:
1: [['10', 'X'], ['11', 'X'], ['12', 'X'], ['13', 'X'], ['14', 'X']] 2: [['9', 'X'], ['10', 'X'], ['11', 'X'], ['12', 'X'], ['13', 'X']] 3: [['8', 'X'], ['9', 'X'], ['10', 'X'], ['11', 'X'], ['12', 'X']] 4: [['7', 'X'], ['8', 'X'], ['9', 'X'], ['10', 'X'], ['11', 'X']] 5: [['6', 'X'], ['7', 'X'], ['8', 'X'], ['9', 'X'], ['10', 'X']] 6: [['5', 'X'], ['6', 'X'], ['7', 'X'], ['8', 'X'], ['9', 'X']] 7: [['4', 'X'], ['5', 'X'], ['6', 'X'], ['7', 'X'], ['8', 'X']] 8: [['3', 'X'], ['4', 'X'], ['5', 'X'], ['6', 'X'], ['7', 'X']] 9: [['2', 'X'], ['3', 'X'], ['4', 'X'], ['5', 'X'], ['6', 'X']]
Reply
#6
(Mar-03-2022, 11:23 PM)Larz60+ Wrote: I would save the dictionary to a json file.
My thoughts exactly. Are you trying to produce a CSV file for external consumption, or are you writing it to save some sort of state for your program? If the latter, the CSV is much harder to work with. With JSON, you can just shove your entire object at it and read it back in later.
Reply
#7
well, i don't even know what a JSON file is and i have other program that uses csv files so my priority is to learn how to manipulate csv files. JSON is something i want to learn to but it is very low on my list of priorities.

Right now i tried to rewrite my program using your exemples
and icame up with this

filename = 'rankedhands.csv'
fields = ['Rank','Hand']

straightlist = {
    '1': [['10', 'X'], ['11', 'X'], ['12', 'X'], ['13', 'X'], ['14', 'X']],
    '2': [['9', 'X'], ['10', 'X'], ['11', 'X'], ['12', 'X'], ['13', 'X']],
    '3': [['8', 'X'], ['9', 'X'], ['10', 'X'], ['11', 'X'], ['12', 'X']],
    '4': [['7', 'X'], ['8', 'X'], ['9', 'X'], ['10', 'X'], ['11', 'X']],
    '5': [['6', 'X'], ['7', 'X'], ['8', 'X'], ['9', 'X'], ['10', 'X']],
    '6': [['5', 'X'], ['6', 'X'], ['7', 'X'], ['8', 'X'], ['9', 'X']],
    '7': [['4', 'X'], ['5', 'X'], ['6', 'X'], ['7', 'X'], ['8', 'X']],
    '8': [['3', 'X'], ['4', 'X'], ['5', 'X'], ['6', 'X'], ['7', 'X']],
    '9': [['2', 'X'], ['3', 'X'], ['4', 'X'], ['5', 'X'], ['6', 'X']]
 }

#x = [{'Rank':key, "Hands":value} for key, value in straightlist.items()]
straightdictlist = []
for key, value in straightlist.items():
    x = {
        'Rank': '',
        'Hand': ''
        }
    x['Rank'] = key
    x['Hand'] = value
    straightdictlist.append(x)
    
    
print(straightdictlist)

with open(filename, 'w') as csvfile:
    csvwriter = csv.DictWriter(csvfile, fieldnames = fields)
    csvwriter.writeheader()
    csvwriter.writerows(csvwriter.writerows(straightdictlist))
and i get this error now

Error:
Traceback (most recent call last): File "/usr/lib/python3.8/idlelib/run.py", line 559, in runcode exec(code, self.locals) File "/home/fook/Documents/pygame/Poker Practice/test.py", line 254, in <module> csvwriter.writerows(csvwriter.writerows(straightdictlist)) File "/usr/lib/python3.8/csv.py", line 157, in writerows return self.writer.writerows(map(self._dict_to_list, rowdicts)) TypeError: 'NoneType' object is not iterable
the file was written ok but i dont understand the error?
Reply
#8
CSV files are extremely limited. If you want to save and restore information about the current state of your program. I strongly suggest using a JSON format file.
Reply
#9
(Mar-04-2022, 12:17 AM)deanhystad Wrote: CSV files are extremely limited. If you want to save and restore information about the current state of your program. I strongly suggest using a JSON format file.

i understand but i don't always choose the type of file that i have to deal with so i must learn to use csv
Reply
#10
That's fine. But CSV only (easily) stores simple text fields. If you want to store a more complex data structure (like nested dicts or nested lists which is what your code shows), you're going to have to perform your own serialization.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  What does .flush do? How can I change this to write to the file? Pedroski55 3 227 Apr-22-2024, 01:15 PM
Last Post: snippsat
  Last record in file doesn't write to newline gonksoup 3 439 Jan-22-2024, 12:56 PM
Last Post: deanhystad
  write to csv file problem jacksfrustration 11 1,548 Nov-09-2023, 01:56 PM
Last Post: deanhystad
  python Read each xlsx file and write it into csv with pipe delimiter mg24 4 1,470 Nov-09-2023, 10:56 AM
Last Post: mg24
  How do I read and write a binary file in Python? blackears 6 6,699 Jun-06-2023, 06:37 PM
Last Post: rajeshgk
  Reading data from excel file –> process it >>then write to another excel output file Jennifer_Jone 0 1,113 Mar-14-2023, 07:59 PM
Last Post: Jennifer_Jone
  Read text file, modify it then write back Pavel_47 5 1,628 Feb-18-2023, 02:49 PM
Last Post: deanhystad
  how to read txt file, and write into excel with multiply sheet jacklee26 14 10,049 Jan-21-2023, 06:57 AM
Last Post: jacklee26
  How to write in text file - indented block Joni_Engr 4 6,469 Jul-18-2022, 09:09 AM
Last Post: Hathemand
  Upgrading from 2 to 3 and having file write problems KenHorse 2 1,498 May-08-2022, 09:47 PM
Last Post: KenHorse

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020