Konstantin
Konstantin

Reputation: 11

Python 3 script for exporting a csv

Hi I have a csv file where there are two columns, one with numbers and one with letters in the following format:

1234  k

343   o

5687  uiuuo

All I want to do is to fill the blank rows with the previous values. I have written that code which saves my work in a new csv but I get an error that says:

b = w[1]
IndexError: list index out of range

This is my code

import csv
with open('col.csv', 'r') as f:
    reader = csv.reader(f)
    my_list = list(reader)
#print my_list[1]
#x = my_list[1]
#print x[0]
x = 0
for count in my_list:
    w = my_list[x]
    a = w[0]
    b = w[1]
    print (a, b)
    #print 'a',  a , 'b', b
    if a == '' and b == '' and x < 3044:
        h = x - 1
        my_list[x] = my_list[h]
        #print 'my_list[x]', my_list[x]
        x = x + 1
        #print my_list[x]
    elif a != '' and b != '' and x < 3044:
        my_list[x] = (a,b)
        x = x + 1
       # print my_list[x]
writer = csv.writer(open('C:/Users/user/Desktop/col2.csv', 'wb'))
#for count in my_list:
data = my_list
for row in data:
    writer.writerow(row)
#print count

Upvotes: 0

Views: 1032

Answers (2)

Wayne Werner
Wayne Werner

Reputation: 51857

When you say

blank lines with previous values

I'm assuming that you want to turn:

1234  k

343   o

5687  uiuuo

Into

1234  k
1234  k
343   o
343   o
5687  uiuuo

You have quite a lot of problems with your code:

import csv
with open('col.csv', 'r') as f:
    reader = csv.reader(f)
    my_list = list(reader)

If you've commented it out you don't need to include it in your question

#print my_list[1]
#x = my_list[1]
#print x[0]

x = 0
for count in my_list:

You do know that your list doesn't contain counts, right? This is just code that lies. Don't do that. Also, if you want to enumerate over a list and get the index along with the value, that's what enumerate is for. It should be for x, value in enumerate(my_list)

    w = my_list[x]
    a = w[0]
    b = w[1]

Your second row doesn't actually have two elements in it. That's why your code fails. Oops.

    print (a, b)
    #print 'a',  a , 'b', b

This code here is a hot mess. Why are you limiting to x < 3044? h is some random variable name that has no meaning. Don't do that either.

    if a == '' and b == '' and x < 3044:
        h = x - 1
        my_list[x] = my_list[h]
        #print 'my_list[x]', my_list[x]
        x = x + 1
        #print my_list[x]
    elif a != '' and b != '' and x < 3044:
        my_list[x] = (a,b)
        x = x + 1
       # print my_list[x]

Don't open files like this, it's possible that they'll never get flushed to disk. Or the entire file won't in any case. Always use a with block!

writer = csv.writer(open('C:/Users/user/Desktop/col2.csv', 'wb'))
#for count in my_list:
data = my_list
for row in data:
    writer.writerow(row)
#print count

So... there's an interesting assumption here - that your first row must not be empty. I mean, I guess it could, but then you're going to be writing empty rows, and maybe you don't want that. Also your provided input doesn't seem to match what you're doing, since you're not using a \t delimiter.

If you think about what you want to do you can come up with the steps pretty easily:

  • for each row in the input file
  • write out that row to the output file
  • if it's blank/empty, write out the previous row

So that's pretty straight forward then.

import csv

with open('input.csv') as infile, open('output.csv', 'w') as outfile:
    reader = csv.reader(infile, delimiter='\t')
    writer = csv.writer(outfile)

    for row in reader:
        writer.writerow(row)

This works - but it doesn't write the previous row if we've got a blank row. Hm. So how can we do that? Well, why not store the previous row? And if the current row is empty, we can write the previous one instead.

    previous_row = []  # If the first row is empty we need an empty list
                       # or whatever you want.
    for row in reader:
        if not row:
            writer.writerow(previous_row)
        else:
            writer.writerow(row)
            previous_row = row

If you want to treat ['', ''] as an empty row, too you just have to tweak the code:

if not row and not all(row):
   ...

Now if the row is empty, or the row contains false-y items it will skip that one as well.

Upvotes: 1

Michriko
Michriko

Reputation: 337

Try not to index elements of an empty list or assign them to variables. Most easy way in your case would be simply clone a complete row.

import csv
with open('col.csv', 'r') as f:
reader = csv.reader(f)
   my_list = list(reader)
for i in range(0,len(my_list)):
   currentLine = my_list[i]
   #Make sure it's not the first line and it's empty, else continue
   if not currentLine and i > 0:
       my_list[i] =my_list[i-1]

with open('C:/Users/user/Desktop/col2.csv','wb') as f:
  writer = csv.writer(f)
  for row in my_list:
      writer.writerow(row)

Upvotes: 0

Related Questions