0

when i'm saving a dictionary representing a graph with the format:

graph_dict = {'b': ['a', 'c'], 'a': [], 'c': ['a'], 'd': []}

and save it with the csv.DictWriter and load it i get:

loaded_graph ={'b': "['a', 'c']", 'c': "['a']", 'a': '[]', 'd': '[]'}

How can i avoid the added quotation marks for the value lists or what code do i have to use to remove them when reading the file? Help would be appreciated!

print(graph_dict)

with open('graph.csv', 'w') as csvfile:

    graph = ['vertices', 'edges']
    writer = csv.DictWriter(csvfile, fieldnames=graph)

    writer.writeheader()

    for vertex in graph_dict:
        edges = graph_dict[vertex]

        writer.writerow({'vertices': vertex, 'edges': edges})


print("reading")

loaded_graph = {}

with open('graph.csv') as csvfile:
    reader = csv.DictReader(csvfile)
    for row in reader:
        loaded_graph[row['vertices']] = row['edges']

print(loaded_graph)

the csv file opened in editor looks like this:

vertices,edges
b,"['a', 'c']"
a,[]
c,['a']
d,[]
  • 1
    Parentheses? Do you mean quotes/quotation marks? CSV is not an appropriate format for nested data structures, so you're already barking up the wrong tree. – ShadowRanger Sep 18 '16 at 14:08
  • Use [JSON instead of CSV](http://stackoverflow.com/questions/17043860/python-dump-dict-to-json-file) and move on. CSV is designed for flat table-like data format, not for arbitrary nested data. Use proper tool for effect you're trying to achieve. – Łukasz Rogalski Sep 18 '16 at 18:35

3 Answers3

0

You have

graph_dict = {'b': ['a', 'c'], 'a': [], 'c': ['a'], 'd': []}

Then

    edges = graph_dict[vertex]
    writer.writerow({'vertices': vertex, 'edges': edges})

This writes a list to the file -- it is converted to str.

Do, for example

writer.writerow({'vertices': vertex, 'edges': ','.join(edges)})
warvariuc
  • 57,116
  • 41
  • 173
  • 227
  • That's just masking tape on the problem, because it means parsing the "poor CSV within true CSV" manually when you read it back in. – ShadowRanger Sep 18 '16 at 14:14
0

CSV is not intended for nested data structures; it has no meaningful way of dealing with them (it's converting your list values to str for output).

You either need to use a more appropriate format (e.g. JSON or pickle), or use horrible hacks to convert the repr of the values back to their original values, e.g. ast.literal_eval (except that won't work properly if some of the original values were supposed to be strings).

ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
0

You're trying to "serialize" this data using CSV, which might be appropriate if you want to analyze the file outside of Python. If not, your problem will be solved more easily with the pickle module.

If you must use CSV, make sure the values you save as "edges" to the file are all strings. Then when you read them back from the file, turn them back to a list.

import csv

graph_dict = {'b': ['a', 'c'], 'a': [], 'c': ['a'], 'd': []}

file_path = 'graph.csv'

with open(file_path, 'w', newline='') as outfile:
    fieldnames = ['vertices', 'edges']
    writer = csv.DictWriter(outfile, fieldnames=fieldnames)
    writer.writeheader()

    for vertex, edges in graph_dict.items():
        # Save multiples as "x,y,z"
        edges = ','.join(edges)
        row = {'vertices': vertex, 'edges': edges}
        writer.writerow(row)

loaded_graph = {}
with open(file_path, 'r', newline='') as infile:
    reader = csv.DictReader(infile)
    for row in reader:
        edges = row['edges']
        # Read empty as [], full as ['x', 'y', 'z']
        edges = edges.split(',') if edges else []
        loaded_graph[row['vertices']] = edges

That gives {'a': [], 'b': ['a', 'c'], 'c': ['a'], 'd': []} as requested.

bbayles
  • 4,389
  • 1
  • 26
  • 34
  • 1
    Thanks a lot for the answers! I'm not that experienced so thanks for the hint to pickle and json. Basicaly i was just looking to store the data after working on it and calling the saved data when beginning the next time. In addition i want to visualize the data in gephi which uses csv (and others). But when i looked it up i found that there is a json importer so my problems is solved. Thanks! – el_flamenco Sep 19 '16 at 14:39