1

I tried to create a csv file from two json files.

First json file :

{ "attributes": [
        {
            "code": "ean",
            "description": "the ean",
            "example": null,
            "hierarchy_code": null,
            "label": "ean",
            "required": true,
            "type": "TEXT",
            "type_parameter": null,
            "values": null,
            "values_list": "some value"
        },
        ...

Second json file :

{
    "code": "the code",
    "label": "shoes",
    "values": [
        {
            "code": "COL_100",
            "label": "white"
        },
        {
            "code": "COL_101",
            "label": "blue"
        },
        ...

I need to get the value from the key "values_list" in the first json. With that key I can get a list from second json (which return a random number of values) and take the "label" key value.

What I’ve found is to make two loop like these :

for att in first_json['attributes']:
    csv_dict[att['values_list']] = []
    for val in second_json['values']:
        csv_dict[att['values_list']].append(val['label'])

Which creates a dictionary like these:

{'label1': [val1, val2, val3], 
'label2': [otherval1, otherval2, ...], 
...}

My question :

With my "csv_dict" dictionary, how can I create a csv structured like this:

label1 | label2    | ... | labeln
val1   | otherval1 | ... | valn
val2   | otherval2 | ... |
val3   | ...       | ... |

My actual dictionary not seems to fit with the usual use of csv.Dictwriter() method.

https://docs.python.org/2/library/csv.html#csv.DictWriter

I try to use the zip function like this :

for elem in zip(*labels.values()):
    data.append(";".join([otherelm for otherelem in elem]))

In hope to create an csv file manually but my attempt failed.

Thanks for your help.

Moerin
  • 45
  • 1
  • 9
  • Can you be more specific how your final result should look like? With `dict[att['values_list']]` you are overwriting the value for the same key (`att['values_list']`) multiple times, is this intentionally? And don't use `dict` as a variable name, since it's the name of the dictionary class in Python. – Jasper Jan 18 '15 at 22:04
  • It's unclear what you mean by "a csv like this: label1 label2 val1 otherval1 val2 otherval2 val3". Please provide more information. – martineau Jan 18 '15 at 22:14
  • I update the my explanations. I hope it'll be clearer. – Moerin Jan 18 '15 at 22:17

2 Answers2

0

Starting from your csv_dict, you can do something like

import csv
import itertools

csv_dict = {'label1': ['val1', 'val2', 'val3'],
            'label2': ['otherval1', 'otherval2'],
            'label3': ['yetanotherval1']}
keys = csv_dict.keys()
csvrows = itertools.izip_longest(*[csv_dict[k] for k in keys], fillvalue='dummy')

with open('out.csv', 'w') as csvfile:
    csvwriter = csv.writer(csvfile, delimiter=';',
                            quotechar='\\', quoting=csv.QUOTE_MINIMAL)
    csvwriter.writerow(keys)
    for row in csvrows:
        csvwriter.writerow(row)

Resulting out.csv:

label1;label2;label3
val1;otherval1;yetanotherval1
val2;otherval2;dummy
val3;dummy;dummy

With the following remarks:

  • When you are zipping the dictionary's values, you should specify the order of the keys
  • What do you want to do if the columns differ in length (in your example, there are val1 to val3, but only two othervals)? Maybe something like padding all lists to fit the longest list?
Community
  • 1
  • 1
Jasper
  • 3,939
  • 1
  • 18
  • 35
  • In my explanation I write some "..." to simulate an infinite number of values. In fact the length in nested list may differ. – Moerin Jan 18 '15 at 22:43
  • See updated answer. And I think that you don't actually mean "infinite" but rather "unknown" :) – Jasper Jan 18 '15 at 22:47
  • "When you are zipping the dictionary's values, you should specify the order of the keys" I can't predict how many keys my dictionary will have, so I thought to use the wild card which can provide a dynamic assignment. But I didn't work with my code. – Moerin Jan 18 '15 at 22:51
  • Please see the updated answer. "Didn't work for me" doesn't help, always state what you did, what you got and what you expected! – Jasper Jan 19 '15 at 10:43
  • The data i used, contained unicode string, so the previous code returned an empty list. But now with this version it's works. I have managed the unicode conversion with the csv library. Thanks for your help. – Moerin Jan 19 '15 at 14:23
-1

OK, I see that you updated your question, so it gives a whole other meaning. Try this:

import csv

labels =  {
    'label1': ["val1", "val2", "val3"],
    'label2': ["otherval1", "otherval2", "otherval3"]
}

keys = [k for k in labels]

with open('file.csv', 'wb') as f
    w = csv.DictWriter(f, keys)
    w.writeheader()
    for group in zip(*labels.values()):
        temp = {}
        for i in group:
            temp[keys[group.index(i)]] = i
        w.writerow(temp)

Try this, it should work for any size of the json object

user2435860
  • 778
  • 3
  • 9
  • 22
  • It was a good idea, same I wanted, but the loop with "*labels.value()" return an empty list. – Moerin Jan 18 '15 at 23:03