Python Forum

Full Version: trying to write a dictionary in a csv file
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2
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
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']]"
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']]"
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'
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']]
(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.
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?
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.
(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
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.
Pages: 1 2