csv writer adds double quotes twice in python - python

I have written a python script to append href attribute and tag to a string holding a url which is in a csv file. The problem is that the result is not as expected. The resulted html string has got an extra double quote instead of single. Any suggestion how to fix this?
Below is the snippet:
InputFile = open('data1.csv', 'rb')
OutputFile = open('data3.csv', 'a+b')
CsvReader_InputFile = csv.reader(InputFile, delimiter=',', quotechar='\"')
CsvWriter_OutputFile = csv.writer(OutputFile, delimiter=',', quotechar='\"')
Row_InputFile = CsvReader_InputFile.next()
Row_InputFile[2] = "Link"
CsvWriter_OutputFile.writerow(Row_InputFile)
Output:
"Link"
Wanted Output:
"Link"

This is correct behaviour. Double quotes are escaped inside csv value.
If you want to output without escaping try csv.QUOTE_NONE
csv.writer(OutputFile, delimiter=',', quotechar='\"', quoting=csv.QUOTE_NONE)

I ran into this when trying to store a JSON object as a string in a column in a csv. I had single quotes around a string filled with double quotes.
my row of data looked like
['foo', 'bar', '{"foo":"bar". "bar":"foo"}']
Doing this solved it for me
writer = csv.writer(csv_file, delimiter=',', quotechar="\'", quoting=csv.QUOTE_NONE)

For those who are having a "Error: need to escape" error:
Try this:
writer = csv.writer(f, quoting=csv.QUOTE_NONE, delimiter='|', quotechar='',escapechar='\\')

Related

Read CSV with comma as linebreak

I have a file saved as .csv
"400":0.1,"401":0.2,"402":0.3
Ultimately I want to save the data in a proper format in a csv file for further processing. The problem is that there are no line breaks in the file.
pathname = r"C:\pathtofile\file.csv"
with open(pathname, newline='') as file:
reader = file.read().replace(',', '\n')
print(reader)
with open(r"C:\pathtofile\filenew.csv", 'w') as new_file:
csv_writer = csv.writer(new_file)
csv_writer.writerow(reader)
The print reader output looks exactly how I want (or at least it's a format I can further process).
"400":0.1
"401":0.2
"402":0.3
And now I want to save that to a new csv file. However the output looks like
"""",4,0,0,"""",:,0,.,1,"
","""",4,0,1,"""",:,0,.,2,"
","""",4,0,2,"""",:,0,.,3
I'm sure it would be intelligent to convert the format to
400,0.1
401,0.2
402,0.3
at this stage instead of doing later with another script.
The main problem is that my current code
with open(pathname, newline='') as file:
reader = file.read().replace(',', '\n')
reader = csv.reader(reader,delimiter=':')
x = []
y = []
print(reader)
for row in reader:
x.append( float(row[0]) )
y.append( float(row[1]) )
print(x)
print(y)
works fine for the type of csv files I currently have, but doesn't work for these mentioned above:
y.append( float(row[1]) )
IndexError: list index out of range
So I'm trying to find a way to work with them too. I think I'm missing something obvious as I imagine that it can't be too hard to properly define the linebreak character and delimiter of a file.
with open(pathname, newline=',') as file:
yields
ValueError: illegal newline value: ,
The right way with csv module, without replacing and casting to float:
import csv
with open('file.csv', 'r') as f, open('filenew.csv', 'w', newline='') as out:
reader = csv.reader(f)
writer = csv.writer(out, quotechar=None)
for r in reader:
for i in r:
writer.writerow(i.split(':'))
The resulting filenew.csv contents (according to your "intelligent" condition):
400,0.1
401,0.2
402,0.3
Nuances:
csv.reader and csv.writer objects treat comma , as default delimiter (no need to file.read().replace(',', '\n'))
quotechar=None is specified for csv.writer object to eliminate double quotes around the values being saved
You need to split the values to form a list to represent a row. Presently the code is splitting the string into individual characters to represent the row.
pathname = r"C:\pathtofile\file.csv"
with open(pathname) as old_file:
with open(r"C:\pathtofile\filenew.csv", 'w') as new_file:
csv_writer = csv.writer(new_file, delimiter=',')
text_rows = old_file.read().split(",")
for row in text_rows:
items = row.split(":")
csv_writer.writerow([int(items[0]), items[1])
If you look at the documentation, for write_row, it says:
Write the row parameter to the writer’s file
object, formatted according to the current dialect.
But, you are writing an entire string in your code
csv_writer.writerow(reader)
because reader is a string at this point.
Now, the format you want to use in your CSV file is not clearly mentioned in the question. But as you said, if you can do some preprocessing to create a list of lists and pass each sublist to writerow(), you should be able to produce the required file format.

Python read csv to dict quotes missing

I have a tab delimited csv file like below:
"land"."monkey" "land"."dog"
"see"."fish" "see"."shell"
which I read and build a dict with:
import argparse
currentSources = open('currentSources.csv', 'r')
find_replace_dict = {}
with currentSources as f:
reader = csv.reader(f,delimiter='\t')
find_replace_dict = dict((rows[0],rows[1]) for rows in reader)
print find_replace_dict
I´d expect the output of find_replace_dict like
{'"land"."monkey"': '"land"."dog"', '"see"."fish"': '"see"."shell"'}
but instead, get it as:
{'land."monkey"': 'land."dog"', 'see."fish"': 'see."shell"'}
Here double-quotes of land and see are missing.
I already tried to tell the reader to quote everything with
reader = csv.reader(f,delimiter='\t',quoting=csv.QUOTE_NONNUMERIC)
which does not bring any difference.
How can I keep all the double-quotes?
When opening your file, explicitly instruct Python that the quotechar is not applicable, and set it to None
The below should help you get the desired output:
with currentSources as f:
reader = csv.reader(f, delimiter='\t', quotechar=None)
reader = csv.reader(currentSources, delimiter='\t', quotechar=None)
Tidying it up by removing the with statement.

Pipe delimiter file, but no pipe inside data

Problem
I need to re-format a text from comma (,) separated values to pipe (|) separated values. Pipe characters within the values of the original (comma separated) text shall be replaced by a space for representation in the (pipe separated) result text.
The pipe separated result text shall be written back to the same file from which the original comma separated text has been read.
I am using python 2.6
Possible Solution
I should read the file first and remove all pipes with spaces in that and later replace (,) with (|).
Is there a the better way to achieve this?
Don't reinvent the value-separated file parsing wheel. Use the csv module to do the parsing and the writing for you.
The csv module will add "..." quotes around values that contain the separator, so in principle you don't need to replace the | pipe symbols in the values. To replace the original file, write to a new (temporary) outputfile then move that back into place.
import csv
import os
outputfile = inputfile + '.tmp'
with open(inputfile, 'rb') as inf, open(outputfile, 'wb') as outf:
reader = csv.reader(inf)
writer = csv.writer(outf, delimiter='|')
writer.writerows(reader)
os.remove(inputfile)
os.rename(outputfile, inputfile)
For an input file containing:
foo,bar|baz,spam
this produces
foo|"bar|baz"|spam
Note that the middle column is wrapped in quotes.
If you do need to replace the | characters in the values, you can do so as you copy the rows:
outputfile = inputfile + '.tmp'
with open(inputfile, 'rb') as inf, open(outputfile, 'wb') as outf:
reader = csv.reader(inf)
writer = csv.writer(outf, delimiter='|')
for row in reader:
writer.writerow([col.replace('|', ' ') for col in row])
os.remove(inputfile)
os.rename(outputfile, inputfile)
Now the output for my example becomes:
foo|bar baz|spam
Sounds like you're trying to work with a variation of CSV - in that case, Python's CSV library might as well be what you need. You can use it with custom delimiters and it will auto-handle escaping for you (this example was yanked from the manual and modified):
import csv
with open('eggs.csv', 'wb') as csvfile:
spamwriter = csv.writer(csvfile, delimiter='|')
spamwriter.writerow(['One', 'Two', 'Three])
There are also ways to modify quoting and escaping and other options. Reading works similarly.
You can create a temporary file from the original that has the pipe characters replaced, and then replace the original file with it when the processing is done:
import csv
import tempfile
import os
filepath = 'C:/Path/InputFile.csv'
with open(filepath, 'rb') as fin:
reader = csv.DictReader(fin)
fout = tempfile.NamedTemporaryFile(dir=os.path.dirname(filepath)
delete=False)
temp_filepath = fout.name
writer = csv.DictWriter(fout, reader.fieldnames, delimiter='|')
# writer.writeheader() # requires Python 2.7
header = dict(zip(reader.fieldnames, reader.fieldnames))
writer.writerow(header)
for row in reader:
for k,v in row.items():
row[k] = v.replace('|'. ' ')
writer.writerow(row)
fout.close()
os.remove(filepath)
os.rename(temp_filepath, filepath)

python argument 1 must have a write method

Hi Im trying to save a modified csv file thats been read. See code.
import csv
with open("Bang.csv", 'rt') as f:
data = f.read()
new_data = data.replace('"', '')
for row in csv.reader(new_data.splitlines(),
delimiter=' ',
skipinitialspace=True):
pa = (','.join(row))
wr = csv.writer("pa", delimiter=',')
wr.writerow("pa")
I can print Data and pa but when I run I get the above mentioned error. What am I missing. Thanks
As mentioned in the manual, the first parameter of csv.writer must be a file-like object.
Suppose you want to write into the stdout (print on the screen), you can modify you code like this:
#pa = (','.join(row)) # you don't need to join row manually
wr = csv.writer(sys.stdout, delimiter=',')
wr.writerow(row)
I really don't know, but I think that the first argument passed to csv.writer( ) function should be a filehandler instead a string variable.

Python Enclosing Words With Quotes In A String

For Python I'm opening a csv file that appears like:
jamie,london,uk,600087
matt,paris,fr,80092
john,newyork,ny,80071
How do I enclose the words with quotes in the csv file so it appears like:
"jamie","london","uk","600087"
etc...
What I have right now is just the basic stuff:
filemame = "data.csv"
file = open(filename, "r")
Not sure what I would do next.
If you are just trying to convert the file, use the QUOTE_ALL constant from the csv module, like this:
import csv
with open('data.csv') as input, open('out.csv','w') as output:
reader = csv.reader(input)
writer = csv.writer(output, delimiter=',', quoting=csv.QUOTE_ALL)
for line in reader:
writer.writerow(line)

Categories

Resources