I want to create a new CSV file with 3 items per row. My source file looks like (there are no new lines / line breaks):
File I/O neutral solution:
csv = """12123, 1324, 232324, 243443, 234, 2345
2334, 2445, 22355, 222234, 2345""" # replace this with the file you read from CSV
def sixPerLineToThreePerLine(s):
result = ""
for line in s.split("\n"):
sp = line.split(", ")
result = result + ", ".join(sp[:3]) + "\n" + ", ".join(sp[3:])
return result
print(sixPerLineToThreePerLine(csv)) # replace this with code to write to CSV
This should help. This was written using python 2.7 so if you have any problems running it in 3.x let me know and I can try to help.
import csv # import the csv module you will need, if you want to avoid this you can just read it in as a text file
output = """""" # make an output string
num = 0 #initialize num that trakcs how many numbers have ben read
with open('datacsv.csv', 'rb') as f: # open the input file
file = csv.reader(f) # initialize the file as being a csv file
for row in file: # for every row (you said no new lines, but just in case)
for data in row: # for ever entry in the row
if(num == 2): # if you have read in three numbers
num = 0 # reset num
output += data + "\n" # output a new line and the current number
else:
num += 1 # increment num
output += data + "," # add to output the data and a comma
new = open("outputcsv.csv", "w") # create the output file
new.write(output) # write the output data to the new file
I wrote a short program that I think does what you wanted:
It reads all lines from the reader file and then just insert them into the writer file 3 by 3 :)
import csv
def main():
with open('ex.csv', 'rb') as f:
reader = csv.reader(f)
with open('ex2.csv', 'wb') as csvfile:
writer = csv.writer(csvfile)
pass_on = []
for row in reader:
#print row
for c in xrange(0, len(row)): # passing on objects after count of 3
if row[c]:
pass_on.append(row[c])
print pass_on
while pass_on:
writer.writerow(pass_on[:3])
pass_on = pass_on[3:]
print "done"
if __name__ == '__main__':
main()
A four-line solution without the csv
module:
with open('oneline_numbers.csv') as fobj_in, open('three_numbers.csv', 'w') as fobj_out:
numbers = iter(entry.strip() for entry in next((fobj_in)).split(','))
for line in zip(*[numbers] * 3):
fobj_out.write(', '.join(line) + '\n')
Here's a solution but it's a bit long. Basically I would write all the values in the csv to a list, then remove three value from the list and write to the csv until there's no values left.
import csv
# just an example csv
with open('example.csv', 'w') as csvfile:
# create example csv with a single row of numbers 0-19
spamwriter = csv.writer(csvfile)
spamwriter.writerow([i for i in range(20)])
# open file for reading, append values to list
l = []
with open('example.csv') as csvfile:
# read the example file into a list
reader = csv.reader(csvfile)
for row in reader:
for val in row:
l.append(val)
# write to the original file with 3 values per line
with open('example.csv', 'w') as csvfile:
spamwriter = csv.writer(csvfile)
while l:
try:
# write to file 3 values at a time
spamwriter.writerow(l[:3])
l = l[3:]
except:
# add last bit of file, if file doesn't devide evenly by 3
spamwriter.writerow(l)
break
I'd recommend checking out Pandas I find it a lot easier to manipulate csvs with it, but it's not in the standard library.
What you want to do is read in the data from the file, then split it into individual elements. Once you have it in individual elements you can put them in groups of three and write to your output file.
Something like this should work:
def read_data(file_path):
with open(file_path, 'r') as fh:
elements = fh.read()
data = [element.strip() for element in elements.split(',')]
return data
def group(data):
grouped = [', '.join(data[n:n+3]) for n in range(0, len(data), 3)]
return grouped
def write(data, output):
with open(output, 'w') as fh:
fh.writelines(data)
def main():
data = read('test.csv')
data = group(data)
write(data, 'test2.csv')