2

I want to create a csv file as follows with 2 column headers as "Y1" and "Y2"

Y1 Y2 
i1 z1
i2 z2
i3 z3

The code I developed is as follows:

with open(r"./file.csv", "a") as f1:
    writer = csv.writer(f1, delimiter="\t", lineterminator="\n")
    row = []
    row_1 = []
    for i in test_data["data"][1]:
        row.append(i)

    for z in test_results:
        row_1.append(z)

    writer.writerow([row, row_1])

I am only getting rows and not the i and z in a different columns. How can write to the csv and get the i and z next to each other in 2 different columns

1
  • So, are test_data['data'][1] and test_results the same size? If so, you can just zip them. I'll show in an answer. Commented Sep 14, 2022 at 17:21

3 Answers 3

2

The "zip" here combines the two lists, so that row is a 2-tuple with one column from each. That's exactly what writerow wants.

with open(r'./file.csv','a') as f1:
    writer=csv.writer(f1, delimiter='\t',lineterminator='\n',)
    for row in zip(test_data['data'][1], test_results):
        writer.writerow(row)

You might even be able to do it in one shot:

with open(r'./file.csv','a') as f1:
    writer=csv.writer(f1, delimiter='\t',lineterminator='\n',)
    writer.writerows( zip(test_data['data'][1], test_results) )

Note "writerows" instead of "writerow".

Sign up to request clarification or add additional context in comments.

Comments

0

And please make sure that you adhere to the RFC-4180 format for CSV files.

It can save you a whole lot of heartache for many edge cases for data containing apostrophes, commas, and quotation marks.

2 Comments

How do you see OP not adhering to RFC-4180... they're using the csv module which is compliant, what's missing?
If its compliant then all good. I was just highlighting to ensure they are aware. Thanks for the update @ZachYoung
0

It's hard to tell without the actual input data, or the actual output, what's going on.

I mocked up some input data like this to satisfy for i in test_data["data"][1]:

test_data = {
    "data": [
        "foo",
        ["Y1", "i1", "i2", "i3"],
    ]
}

and for z in test_results:

test_results = ["Y2", "z1", "z2", "z3"]

Now, when I run your code as-is, I get an output CSV that looks like:

['Y1', 'i1', 'i2', 'i3']    ['Y2', 'z1', 'z2', 'z3']

(I assume your header isn't in the actual input, but I included it just to make your small example code work.)

Following @Tim Roberts' suggestion, using zip() is probably the most correct way to join your two columns:

rows = zip(test_data["data"][1], test_results)

print(list(rows))

and we can see that the values from data and results have been properly joined:

[
    ("Y1", "Y2"),
    ("i1", "z1"),
    ("i2", "z2"),
    ("i3", "z3"),
]

From here, using the csv writer is just a few lines of code:

with open("output.csv", "w", newline="") as f_out:
    writer = csv.writer(f_out, delimiter="\t", lineterminator="\n")
    writer.writerows(rows)

and I get:

Y1  Y2
i1  z1
i2  z2
i3  z3

To me, the most important concept to take away is get your data set up first (like we can see in that print(list(rows)) statement), then do the CSV writing stuff.

Here's the complete program:

import csv

test_data = {
    "data": [
        "foo",
        ["Y1", "i1", "i2", "i3"],
    ]
}

test_results = ["Y2", "z1", "z2", "z3"]

rows = zip(test_data["data"][1], test_results)

with open("output.csv", "w", newline="") as f_out:
    writer = csv.writer(f_out, delimiter="\t", lineterminator="\n")
    # writer.writerow(["Y1", "Y2"])  # if you need to write your header manually
    writer.writerows(rows)

I also don't see a need to append: get your data composed and sorted, then just "write" to the CSV file, once.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.