Python Forum

Full Version: writing numbers to csv file
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Greetings,

can someone tell me wether the following is correct?
I have float values stored in two lists, namely x2 and y2.
I want to print a csv file with delimiter " ", in which the i-th element of x2 stands next to the i-th element of y2 in the i-th row.

with open(outputname, mode='w') as csv_output:
	result_writer=csv.writer(csv_output, delimiter=" ")
	for j in range(len(x2)):	
		result_writer.writerow(x2[j], y2[j])
outputname is a string of the name of the outputfile that is to be created, namely "outputfile.csv".



Regards!
I would say that you have to pass the list of columns to the writerow() function:

import csv

x2 = [1, 2, 3]
y2 = ["a", "b", "c"]

with open("./outputfile.csv", "w") as file:
    csv_writer = csv.writer(file, delimiter=" ")
    for i in range(0, len(x2)):
        csv_writer.writerow(
            [
                str(x2[i]),
                str(y2[i])
            ]
        )
with open(outputname, mode='w') as csv_output:
    result_writer=csv.writer(csv_output, delimiter=" ")
    
    # option 1
    for nums in zip(x2, y2):    
        result_writer.writerow(nums) # here you need to pass iterable, e.g. list, tuple, etc.
        
    # option 2 - alternative to option 1
    data = (nums for nums in zip(x2, y2))
    result_writer.writerows(data) # here you need to pass list of lists, etc. Here we pass generator expression that will yield tuples
EDIT:Option 2 can be simplified further
(Dec-19-2018, 11:33 AM)buran Wrote: [ -> ]
with open(outputname, mode='w') as csv_output:
    result_writer=csv.writer(csv_output, delimiter=" ")
    
    # option 1
    for nums in zip(x2, y2):    
        result_writer.writerow(nums) # here you need to pass iterable, e.g. list, tuple, etc.
        
    # option 2 - alternative to option 1
    data = (nums for nums in zip(x2, y2))
    result_writer.writerows(data) # here you need to pass list of lists, etc. Here we pass generator expression that will yield tuples

Why so complicated? What would be the problem with ODIS' solution?
(Dec-19-2018, 12:31 PM)SchroedingersLion Wrote: [ -> ]Why so complicated? What would be the problem with ODIS' solution?
It's simpler than ODIS solution - 2 lines (use either option1 or option2).

What I don't like with ODIS' solution (no offence, please):
1. using range(len(iterable)) to loop - read https://python-forum.io/Thread-Basic-Nev...n-sequence
2. why construct list in each iteration, when you can use zip to combine both lists and iterate simultaneously over both lists?
3. no need to cast variables to str
4. if we write ODIS' solution on two lines
for i in range(0, len(x2)):
    csv_writer.writerow([str(x2[i]), str(y2[i])])
or even if we look at it as is, which one is more readable? Compare with

for nums in zip(x2, y2):    
    result_writer.writerow(nums)
or

data = (nums for nums in zip(x2, y2))
result_writer.writerows(data)
Of course, it works - feel free to use any one you like most.
Thank you, I will give it a try this afternoon!
Actually option2 can be simplified even further
data = zip(x2, y2)
result_writer.writerows(data)
or even as one-liner
result_writer.writerows(zip(x2, y2))
For SchroedingersLion sake I add one additional tidbit to consider when comparing those two solutions:

(Dec-19-2018, 12:58 PM)buran Wrote: [ -> ]Actually option2 can be simplified even further
data = zip(x2, y2)
result_writer.writerows(data)
or even as one-liner
result_writer.writerows(zip(x2, y2))

zip() produces iterator and you can consume it only once. Depending on your needs and in order to avoid nasty surprises you should be aware of following (expected) behaviour:

>>> x = [1, 2, 3]
>>> y = [4, 5, 6]
>>> zipped = zip(x, y)       # iterator created
>>> list(zipped)             # iterator consumed
[(1, 4), (2, 5), (3, 6)]
>>> list(zipped)             # exhausted iterator           
[]
>>> list(zip(x, y))          # iterator created and consumed
[(1, 4), (2, 5), (3, 6)]
>>> list(zip(x, y))          # iterator created again and consumed
[(1, 4), (2, 5), (3, 6)]