csv.writer exports horizontally - python

I have a list filled with values. I want to export the list to a .csv file.
I want the values to be on top of each other, yet right now they get exported next to each other.
e.g. I want it to be like:
1
2
3
not
1 2 3
How do I have to change my code?
with open('C:(...)file.csv', "w", newline='\n') as csfile:
wr = csv.writer(csfile, delimiter =';')
wr.writerow([item[0] for item in sntlst])
It is important to receive item[0] of my list.

Change the delimiter argument to '\n':
with open('C:(...)file.csv', "w", newline='\n') as csfile:
wr = csv.writer(csfile, delimiter='\n')
wr.writerow([item[0] for item in sntlst])
The newline='\n' isn't even necessary, so you can do without it:
with open('C:(...)file.csv', "w") as csfile:
wr = csv.writer(csfile, delimiter='\n')
wr.writerow([item[0] for item in sntlst])

The answer you have accepted (by #Ann Zen) may work, but that's due to a fluke because technically it's abusing the use of delimiter keyword argument with respect to the sample shown in the documentation of opening files for a csv.writer — and because of that it might now work properly on all platforms.
So, that said, in my opinion the code shown below would be a proper and better way to do things. It makes each item in your list a "row" of one item in the CSV file that's being created.
import csv
sntlst = [1, 2, 3]
output_file_path = 'list_file.csv'
with open(output_file_path, "w", newline='') as csvfile:
wr = csv.writer(csvfile)
wr.writerows([item] for item in sntlst)

Related

What function is used to iterate through a list of lists and only print specific rows to the console?

For the last part of a Python assignment, I need to iterate through the lists of lists and print to the console the rows with category 'Hardware'. This is the csv file:
Hardware,Hammer,10,10.99
Hardware,Wrench,12,5.75
Food,Beans,32,1.99
Paper,Plates,100,2.59
The following is the code for the last part, which simply opens the file to be read and passed into a list:
def read_text():
with open("products.csv", "r", newline="") as file:
reader = csv.reader(file)
temp_prod = list(reader)
I'm having an issue with coding the right for loop to pull out the 'Hardware' rows. Help would be appreciated! Thanks.
When you are stuck, try to do a lot of printing to see what is going on. You were in a good point. temp_prod gave you a list of lists. You have to iterate through this list of list and ask if the first item is equal to your search criteria.
You code should look like that:
def read_text(my_file):
import csv
with open(my_file, "r", newline="") as file:
reader = csv.reader(file)
temp_prod = list(reader)
for row in temp_prod:
if row[0] == "Hardware":
print(row)
Call the function that way:
read_text("filepath.csv")
Please note that this function (as you requested) doesn't return anything, it only prints.

List to csv without commas in Python

I have a following problem.
I would like to save a list into a csv (in the first column).
See example here:
import csv
mylist = ["Hallo", "der Pixer", "Glas", "Telefon", "Der Kühlschrank brach kaputt."]
def list_na_csv(file, mylist):
with open(file, "w", newline="") as csv_file:
csv_writer = csv.writer(csv_file)
csv_writer.writerows(mylist)
list_na_csv("example.csv", mylist)
My output in excel looks like this:
Desired output is:
You can see that I have two issues: Firstly, each character is followed by comma. Secondly, I don`t know how to use some encoding, for example UTF-8 or cp1250. How can I fix it please?
I tried to search similar question, but nothing worked for me. Thank you.
You have two problems here.
writerows expects a list of rows, said differently a list of iterables. As a string is iterable, you write each word in a different row, one character per field. If you want one row with one word per field, you should use writerow
csv_writer.writerow(mylist)
by default, the csv module uses the comma as the delimiter (this is the most common one). But Excel is a pain in the ass with it: it expects the delimiter to be the one of the locale, which is the semicolon (;) in many West European countries, including Germany. If you want to use easily your file with your Excel you should change the delimiter:
csv_writer = csv.writer(csv_file, delimiter=';')
After your edit, you want all the data in the first column, one element per row. This is kind of a decayed csv file, because it only has one value per record and no separator. If the fields can never contain a semicolon nor a new line, you could just write a plain text file:
...
with open(file, "w", newline="") as csv_file:
for row in mylist:
print(row, file=file)
...
If you want to be safe and prevent future problems if you later want to process more corner cases values, you could still use the csv module and write one element per row by including it in another iterable:
...
with open(file, "w", newline="") as csv_file:
csv_writer = csv.writer(csv_file, delimiter=';')
csv_writer.writerows([elt] for elt in mylist)
...
l = ["Hallo", "der Pixer", "Glas", "Telefon", "Der Kühlschrank brach kaputt."]
with open("file.csv", "w") as msg:
msg.write(",".join(l))
For less trivial examples:
l = ["Hallo", "der, Pixer", "Glas", "Telefon", "Der Kühlschrank, brach kaputt."]
with open("file.csv", "w") as msg:
msg.write(",".join([ '"'+x+'"' for x in l]))
Here you basically set every list element between quotes, to prevent from the intra field comma problem.
Try this it will work 100%
import csv
mylist = ["Hallo", "der Pixer", "Glas", "Telefon", "Der Kühlschrank brach kaputt."]
def list_na_csv(file, mylist):
with open(file, "w") as csv_file:
csv_writer = csv.writer(csv_file)
csv_writer.writerow(mylist)
list_na_csv("example.csv", mylist)
If you want to write the entire list of strings to a single row, use csv_writer.writerow(mylist) as mentioned in the comments.
If you want to write each string to a new row, as I believe your reference to writing them in the first column implies, you'll have to format your data as the class expects: "A row must be an iterable of strings or numbers for Writer objects". On this data that would look something like:
csv_writer.writerows((entry,) for entry in mylist)
There, I'm using a generator expression to wrap each word in a tuple, thus making it an iterable of strings. Without something like that, your strings are themselves iterables and lead to it delimiting between each character as you've seen.
Using csv to write a single entry per line is almost pointless, but it does have the advantage that it will escape your delimiter if it appears in the data.
To specify an encoding, the docs say:
Since open() is used to open a CSV file for reading, the file will by
default be decoded into unicode using the system default encoding (see
locale.getpreferredencoding()). To decode a file using a different
encoding, use the encoding argument of open:
import csv with open('some.csv', newline='', encoding='utf-8') as f:
reader = csv.reader(f)
for row in reader:
print(row)
The same applies to writing in something other than the system default encoding: specify the encoding argument when
opening the output file.
try split("\n")
example:
counter = 0
amazing list = ["hello","hi"]
for x in titles:
ok = amazinglist[counter].split("\n")
writer.writerow(ok)
counter +=1

How to remove delimiters when reading csv file in Python?

Just trying to learn python and trying to help a friend with taking a column from a .csv file to print it with a label-maker. The first problem I came across is this:
I will use this example file: test.csv
1111,2222,3333,4444
aaaa,bbbb,cccc,dddd
aaaa,bbbb,cccc,dddd
I run it trough:
import csv
with open('test.csv', 'r') as csv_File:
csv_reader = csv.reader(csv_File)
with open('test2.csv', 'w') as new_file:
csv_writer = csv.writer(new_file)
for line in csv_reader:
(csv_writer).writerow(line[1])
and get the output:
2,2,2,2
b,b,b,b
b,b,b,b
I want the output:
2222
bbbb
bbbb
what am I doing wrong?
writerow is expecting a whole list to write as a row, just as you got a whole list from the reader. To output one field only you should wrap it in a list:
csv_writer.writerow([line[1]])
But note it would be simpler to just write the data directly, since you don't need any of the functionality that the CSV writer gives you:
with open('test2.csv', 'w') as new_file:
for line in csv_reader:
new_file.write(line[1])
writerow takes a iterable of data of one row. You provide it a single string that gets interpreted as iterable and each element gets printed as column.
Fix:
csv_writer.writerow([line[1]]) # put the string into a list so you provide a single item row

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: Write nested list objects to csv file

I'm trying to write data from a list of lists to a csv file. This is a simplified version of what I have
class Point(object):
def __init__(self, weight, height):
self.weight = weight
self.height = height
def get_BMI(self):
return (self.weight * self.height) / 42 # this is not how you calculate BMI but let's say
myList = [[Point(30, 183)],[Point(63, 153)]]
Because of the way the data is set up, I store the points in a nested loop. If I wanted to access the first point object’s BMI, I would type
myList[0][0].get_BMI()
I want to write each point's BMI to a CSV (delimited by a comma). How do I do that?
Here's how I thought but it isn't exactly straight forward:
import csv
with open('output.csv', 'w') as csvfile:
writer = csv.writer(csvfile)
writer.writerows(myList)
It doesn't return any error however it doesn't actually create the CSV file either. Also I want to write the values in myList[i][j].get_BMI() to file. I don't have a problem with permissions because I use Spyder (python IDE) as root. Right now I'm just running the script through the Spyder console but it should still work and output the CSV file.
writerows expects a list of list of strings or numbers. You should start by creating a list with the BMI values so that they can get written into your csv file:
import csv
BMIs = [[point.get_BMI() for point in points] for points in myList]
with open('output.csv', 'w') as csvfile:
writer = csv.writer(csvfile)
writer.writerows(BMIs)
You can do this with writerows, as it expects a list of rows - each row should be formatted as per the dialect parameter to csv.writer, which can be ignored in this case without fear of any backfiring.
So writerows can take a structure that looks like myList. The problem is that you need to access all the points and grab their BMIs (this can be done in a list comprehension)
To illustrate how writerows can be used (and to add a number to each point, so that all your rows don't have just one entry (which would be frustrating), I added the call to enumerate.
Therefore, you no longer need complex loops or any such. Enjoy:
myList = [[Point(30, 183)],[Point(63, 153)]]
with open('output.csv', 'w') as outfile:
writer = csv.writer(outfile)
writer.writerows(enumerate(p.get_BMI() for p in itertools.chain.from_iterable(myList)))
There are three issues:
The nested lists must be flattened. To accomplish this, use itertools.chain.from_iterable.
The row data for the CSV must be customized. To accomplish this, use list comprehensions.
output.csv is not being created. I suspect that the output.csv is being created but being placed in an unexpected location. You could try hardcoding a full path for testing to see if this is the case.
Here is code that demonstrates #1 and #2:
import csv
from itertools import chain
with open('output.csv', 'w') as csvfile:
writer = csv.writer(csvfile)
flattenedList = chain.from_iterable(myList)
writer.writerows((pt.weight, pt.height, pt.get_BMI()) for pt in flattenedList)
myList = [[Point(30, 183)],[Point(63, 153)]]
with open('output.csv', 'w') as outfile:
writer = csv.writer(outfile,delimiter=',')
for i in myList:
writer.writerow([i])

Categories

Resources