I'm copying the contents of a csv file and writing these to another so I can modify it later but can't figure out what the simple solution is. I thought I could keep the input csv_file and output writer files open while copying the contents, don't know if that's a good idea. My code
import csv, os
file_path = 'path/to/file.csv'
output_path = os.path.dirname(os.path.abspath(file_path)) + '/'
with open(file_path) as csv_file:
data_source = csv.reader(csv_file, delimiter=',')
with open(output_path + 'results.csv', 'w', newline='') as writer:
for line in data_source:
writer.writerow(line)
This is the error I get:
AttributeError: '_io.TextIOWrapper' object has no attribute 'writerow'
The object that you think is the writer is not. Instead, you should construct the writer separately.
with open(file_path) as csv_file:
data_source = csv.reader(csv_file, delimiter=',')
with open(output_path + 'results.csv', 'w', newline='') as results_file:
data_sink = csv.writer(results_file) #This is the important line
for line in data_source:
data_sink.writerow(line)
Can you try this code and see if this works?
import csv, os
file_path = 'path/to/file.csv'
output_path = os.path.dirname(os.path.abspath(file_path)) + '/'
with open(file_path) as csv_file:
data_source = csv.reader(csv_file, delimiter=',')
f = open(output_path + 'results.csv', 'w', newline='')
with f:
writer = csv.writer(f)
for line in data_source:
writer.writerow(line)
The error means that there is no method for writerow for the writer.
Related
I'm trying to write csv file from a list:
list:
newest = ['x11;y11;z11', 'x12;y12;z12', 'x13;y13;z13', 'x14;y14;z14', 'x15;y15;z15', 'x16;y16;z16', 'x17;y17;z17', 'x18;y18;z18', 'x19;y19;z19', 'x20;y20;z20']
My actual code:
with open(r'listtocsv.csv', 'w', newline='\n') as myfile:
wr = csv.writer(myfile, quoting=csv.QUOTE_ALL, delimiter=';')
wr.writerow(newest)
My actual result:
Result wanted:
import csv
newest = ['x11;y11;z11', 'x12;y12;z12', 'x13;y13;z13', 'x14;y14;z14', 'x15;y15;z15', 'x16;y16;z16', 'x17;y17;z17', 'x18;y18;z18', 'x19;y19;z19', 'x20;y20;z20']
new = []
for i in newest:
new.append(i.split(";"))
with open("file.csv", "w", newline="") as f:
writer = csv.writer(f)
writer.writerows(new)
output:
I have many CSV files, need to read all the files in loop and write file name and all the columns (header in row 1) in an output file.
Example
Input csv file 1 (test1.csv)
Id, Name, Age, Location
1, A, 25, India
Input csv file 2 (test2.csv)
Id, ProductName
1, ABC
Outputfile
test1.csv Id
test1.csv Name
test1.csv Age
test1.csv Location
test2.csv Id
test2.csv ProductName
Many thanks for your help.
Update:
This code works fine for this purpose:
import os
import csv
ofile = open('D:\Anuj\Personal\OutputFile/AHS_File_Columns_Info.csv', 'w')
directory = os.path.join('D:\Anuj\Personal\Python')
for root, dirs, files in os.walk(directory):
for file in files:
fullfilepath = directory + "/" + file
with open(fullfilepath,'r') as f:
output = file +','+ f.readline()
ofile.write(output)
clean solution using csv module for reading and writing
open output file and create a csv.writer instance on its handle
open each input file and create a csv.reader instance on their handle
get first row using next on the csv.reader iterator: gets titles as list (with a small post-processing to remove the spaces)
write titles alongside the current filename in a loop
code:
import csv
files=["test1.csv","test2.csv"]
with open("output.tsv","w",newline='') as fw:
cw = csv.writer(fw,delimiter="\t") # output is tab delimited
for filename in files:
with open(filename,'r') as f:
cr = csv.reader(f)
# get title
for column_name in (x.strip() for x in next(cr)):
cw.writerow([filename,column_name])
There are several advantages using csv module, the most important being that quoting & multi-line fields/titles are managed properly.
But I'm not sure I understand you correctly.
import csv
from typing import List
from typing import Tuple
TableType = List[List[str]]
def load_csv_table(file_name: str) -> Tuple[List[str], TableType]:
with open(file_name) as csv_file:
csv_reader = csv.reader(csv_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
headers = next(csv_reader)
data_table = list(csv_reader)
return headers, data_table
def save_csv_table(file_name: str, headers: List[str], data_table: TableType):
with open(file_name, 'w', newline='') as csv_file:
writer = csv.writer(csv_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
writer.writerow(headers)
for row in data_table:
writer.writerow(row)
input_files = ['file1.csv', 'file2.csv', 'file3.csv']
new_table = []
new_headers = []
for file_name in input_files:
headers, data_table = load_csv_table(file_name)
if not new_headers:
new_headers = ['Source'] + headers
new_table.extend(([file_name] + line for line in data_table))
save_csv_table('output.csv', new_headers, new_table)
A simple method is to use readline() on the file object:
files=["test1.csv","test2.csv"]
for my_file in files:
with open(my_file,'r') as f:
print my_file, f.readline()
I'm trying to generate the csv with delimiter '#|#' but, I couldn't achieve through below code.
import csv
ifile = open('test.csv', "rb")
reader = csv.reader(ifile)
ofile = open('ttest.csv', "wb")
writer = csv.writer(ofile, delimiter='|', quotechar='"', quoting=csv.QUOTE_ALL)
for row in reader:
writer.writerow(row)
ifile.close()
ofile.close()
While running, It has thrown below error.
Traceback (most recent call last):
File "csvfile.py", line 6, in <module>
writer = csv.writer(ofile, delimiter='#|#', quotechar='"', quoting=csv.QUOTE_ALL)
TypeError: "delimiter" must be an 1-character string
How can I achieve this?
In csv documentation they say
A one-character string used to separate fields. It defaults to ','.
So you can do this as an alternative.
csv.reader((line.replace('#|#', '|') for line in ifile), delimiter='|')
So the complete code is,
import csv
ifile = open('test.csv', "rb")
reader = csv.reader((line.replace('#|#', '|') for line in ifile), delimiter='|')
ofile = open('ttest.csv', "wb")
writer = csv.writer(ofile, delimiter='|', quotechar='"', quoting=csv.QUOTE_ALL)
for row in reader:
writer.writerow(row)
ifile.close()
ofile.close()
The csvfile argument to the csv.writer constructor only has to be a "file-like object". This means you could supply an instance of your own class which changes a single character into one with two or more characters (but which otherwise acts like a open output file object).
Here's what I mean:
import csv
class CSV_Translater(object):
""" Output file-like object that translates characters. """
def __init__(self, f, old, new):
self.f = f
self.old = old
self.new = new
def write(self, s):
self.f.write(s.replace(self.old, self.new))
def close(self):
self.f.close()
def flush(self):
self.f.flush()
with open('in_test.csv', "rb") as ifile:
reader = csv.reader(ifile)
with open('out_test.csv', "wb") as ofile:
translater = CSV_Translater(ofile, '|', '#|#')
writer = csv.writer(translater, delimiter='|', quotechar='"',
quoting=csv.QUOTE_ALL)
for row in reader:
writer.writerow(row)
I have a list like this(python 3)
my_list = [["xxx","moon",150],["wordq","pop",3]]
and i save it on a csv using this code
import csv
myfile = open("pppp.csv", 'wb')
with open("pppp.csv", "w", newline='') as myfile:
wr = csv.writer(myfile, quoting=csv.QUOTE_NONE)
wr.writerows(list_of_DVDsuppliers)
now i need to export this csv in to my program as a list and change the data .
please help me ?
Just convert the data you get from reader() to a list:
data = csv.reader(open('example.csv','r'))
data = list(data)
print data
Unless you have a reason why you are using newline='', you can skip that and below code works with python 2.7,
import csv
my_list = [["xxx","moon",150],["wordq","pop",3]]
myfile = open("pppp.csv", 'wb')
with open("pppp.csv", "w") as myfile:
wr = csv.writer(myfile, quoting=csv.QUOTE_NONE)
wr.writerows(my_list)
data = csv.reader(open('pppp.csv','r'))
for row in data:
print row
EDIT: Thanks for the answers guys, got what I needed!!
Basically I am trying to take what I have stored in my textfile and I am trying to write that into a .csv file. In my file are tweets that I have stored and I am trying to have one tweet in each cell in my .csv file.
Right now it is only taking one tweet and creating a .csv file with it and I need it to take all of them. Any help is greatly appreciated. Here is what I have so far.
with open('reddit.txt', 'rb') as f:
reader = csv.reader(f, delimiter=':', quoting = csv.QUOTE_NONE)
for row in reader:
print row
cr = csv.writer(open('reddit.csv', 'wb'))
cr.writerow(row)
You'll need to create the writer outside of the loop:
with open('reddit.txt', 'rb') as input_file:
reader = csv.reader(input_file, delimiter=':', quoting = csv.QUOTE_NONE)
with open('reddit.csv', 'wb') as output_file:
writer = csv.writer(output_file)
for row in reader:
writer.writerow(row)
Although here it might be cleaner to open the files without with:
input_file = open('reddit.txt', 'rb')
output_file = open('reddit.csv', 'wb')
reader = csv.reader(input_file, delimiter=':', quoting=csv.QUOTE_NONE)
writer = csv.writer(output_file)
for row in reader:
writer.writerow(row)
input_file.close()
output_file.close()
Or you can still use with and just have a really long line:
with open('reddit.txt', 'rb') as input_file, open('reddit.csv', 'wb') as output_file:
reader = csv.reader(input_file, delimiter=':', quoting = csv.QUOTE_NONE)
writer = csv.writer(output_file)
for row in reader:
writer.writerow(row)
The line cr = csv.writer(open('reddit.csv', 'wb')) is inside the for loop. You need to open the file just once, place this line after
reader = csv.reader(f, delimiter=':', quoting = csv.QUOTE_NONE)
Then write to it as you did in each loop iteration.