BillyPocheo
BillyPocheo

Reputation: 93

Write a csv file from a dictionary with compound keys

I have a dictionary whose keys are tuples of 2 items. I would like to write this dictionary as a .csv file.

My dictionary counter looks like this :

{("Banana", "Apple") : 1,
 ("Apple", "Pear") : 2,
 # ...
}

I've tried this:

header = ['group', 'list', 'id']
with open("file.csv", 'w') as f2:
    writer = csv.DictWriter(f2, fieldnames=header)
    writer.writeheader()
    for key, val in counter.items(): 
        write.writerow([key]+val)

But I get this error:

TypeError: can only concatenate list (not "int") to list

Can somebody help me?

Edit

I've tried with this, too:

with open("file.csv", 'w+') as f2:
    writer = csv.DictWriter(f2, fieldnames=header)
    writer.writeheader()
    for key, val in counter.items():
        writer.writerow(key,val)

But it now says:

TypeError: writerow() takes 2 positional arguments but 3 were given

Upvotes: 1

Views: 268

Answers (3)

martineau
martineau

Reputation: 123501

From the sample of the contents of the counter dictionary you added, I now understand what you're trying to do.

Here's how to accomplish what you want:

import csv

counter = {("Banana", "Apple"): 1,
           ("Apple", "Pear"): 2,
           # ...
          }

header = 'group', 'list', 'id'
with open("compound_keys.csv", 'w', newline='') as f:
    writer = csv.DictWriter(f, fieldnames=header)
    writer.writeheader()
    for (group, list_), id in counter.items():
        writer.writerow(dict(zip(header, (group, list_, id))))

Contents of .csv file created:

group,list,id
Banana,Apple,1
Apple,Pear,2

Note

It would be simpler and more efficient in this case to use a csv.writer instead of a csv.DictWriter because then it wouldn't be nesssary to create a temporary dictionary to write each row of the output file (only a tuple).

The following produces exactly the same results:

header = 'group', 'list', 'id'
with open("compound_keys.csv", 'w', newline='') as f:
    writer = csv.writer(f)
    writer.writerow(header)
    for (group, list_), id in counter.items():
        writer.writerow((group, list_, id))

Upvotes: 1

Bill Chen
Bill Chen

Reputation: 1749

How about using the plain with open:

with open("file.csv", 'a+') as f:
    f.write('group' + ',' + 'list' + ',' + 'id'
    for key, value in f2.items():
        f.write(key[0] + ',' + key[1] + ',' + str(value))

Upvotes: 0

Stan van Rooy
Stan van Rooy

Reputation: 346

As already mentioned by martineau, we can't really help without knowing what counter is, however, I think I see what's going wrong.

What you're saying is not possible. Every dictionary has an equal amount of keys as values, a key can't exist without a value.

From your question, I think this is what you're looking for:

header = ['group', 'list', 'id']
with open('file.csv', 'w+') as f:
    writer = csv.DictWriter(f, fieldnames=header)
    writer.writeheader()
    keys = list(counter.keys())
    values = list(counter.items())
    writer.writerow([keys[0], keys[1], values[0]])

Upvotes: 0

Related Questions