-1

I have this script that reads a CSV and saves the second column to a list, I'm trying to get it to write the contents of the list to a new CSV. The problem is every entry should have its own row but the new file sets everything into the same row.

I've tried moving the second with open code to within the first with open and I've tried adding a for loop to the second with open but no matter what I try I don't get the right results.

Here is the code:

import csv
col_store=[]      
with open('test-data.csv', 'r') as rf:
    reader = csv.reader(rf)
    for row in reader:
        col_store.append(row[1])
with open('meow.csv', 'wt') as f:
    csv_writer = csv.writer(f)
    csv_writer.writerows([col_store])
halfer
  • 19,824
  • 17
  • 99
  • 186
robothead
  • 303
  • 2
  • 10

2 Answers2

2

In your case if you have a column of single letters/numbers then Y.R answer will work.

To have a code that works in all cases, use this.

with open('meow.csv', 'wt') as f:
    csv_writer = csv.writer(f)
    csv_writer.writerows(([_] for _ in col_store))

From here it is mentioned that writerows expect an an iterable of row objects. Every row object should be an iterable of strings or numbers for Writer objects

Sam Daniel
  • 1,800
  • 12
  • 22
  • thanks this worked but even after looking at the doc you linked to I dont quite understand why. – robothead Jun 11 '20 at 20:09
  • A row in a csv is a list of elements.. So when you want to `writerows`, you should pass a list of list-of-elements. btw, i am using the term list to easily understand, in reality all it expects is a iterable type. – Sam Daniel Jun 11 '20 at 20:14
1

The problem is that you are using 'writerows' treating 'col_store' as a list with one item.

The simplest approach to fixing this is calling

csv_writer.writerows(col_store)
# instead of 
csv_writer.writerows([col_store])

However, this will lead to a probably unwanted result - having blank lines between the lines.

To solve this, use:

with open('meow.csv', 'wt', newline='') as f:
     csv_writer = csv.writer(f)
     csv_writer.writerows(col_store)

For more about this, see CSV file written with Python has blank lines between each row

Note: writerows expects 'an iterable of row objects' and 'row objects must be an interable of strings or numbers'. (https://docs.python.org/3/library/csv.html) Therefore, in the generic case (trying to write integers for examlpe), you should use Sam's solution.

Y.R.
  • 371
  • 1
  • 7
  • Thanks, that works but now each row has all these commas. this column held skus so it each row should have something like ba0011 instead its showing b,a,0,0,1,1 – robothead Jun 11 '20 at 20:02
  • Which commas exactly? could you give the exact example? – Y.R. Jun 11 '20 at 20:05
  • Shouldn't this lead to an error? `_csv.Error: iterable expected, not int (something similar)` – Sam Daniel Jun 11 '20 at 20:16
  • Looking at the example I don't think it should. Note that col_store is initiated to be a list and items are added using .append method, which makes it an iterable. – Y.R. Jun 11 '20 at 20:18
  • I think it works not because of that reason, it works because every element in that list is a string. So strings are iterable. so its an iterable of iterables.. but yes it works. – Sam Daniel Jun 11 '20 at 20:31