Python CSV: IndexError: List Index out of range - python

I have very weird problem in working with csv. My code is :
with open('CFD.csv', 'rt') as f:
reader = csv.reader(f, delimiter=',')
for row in reader:
if cfd_number == row[0]:
cfd_checked_before = "Yes"
This code is working in Mac but in windows, I get the following error:
IndexError: List Index out of range

Its common to have empty lines in csv files, especially at the end of the file. If you want your code to accept this common error, just check the row list before use.
with open('CFD.csv', 'rt') as f:
reader = csv.reader(f, delimiter=',')
for row in reader:
if row:
if cfd_number == row[0]:
cfd_checked_before = "Yes"
You can also use filter for the same task. When its first parameter is None, it removes "falsey" things like empty lists:
with open('CFD.csv', 'rt') as f:
reader = csv.reader(f, delimiter=',')
for row in filter(None, reader):
if cfd_number == row[0]:
cfd_checked_before = "Yes"

There are maybe some possible cases there...
Maybe you are opening a csv file in Windows not even alike as the csv file you are using in Mac
Maybe the problem there is in the line row[0]
Maybe your csv file does not contains any comma delimiter or some rows there has an empty line as stated.
try printing the row variable or even the reader variable

Related

Delete rows from csv file using function in Python

def usunPsa(self, ImiePsa):
with open('schronisko.csv', 'rb') as input, open('schronisko.csv', 'wb') as output:
writer = csv.writer(output)
for row in csv.reader(input):
if row[0] == ImiePsa:
writer.writerow(row)
with open(self.plik, 'r') as f:
print(f.read())
Dsac;Chart;2;2020-11-04
Dsac;Chart;3;2020-11-04
Dsac;Chart;4;2020-11-04
Lala;Chart;4;2020-11-04
Sda;Chart;4;2020-11-04
Sda;X;4;2020-11-04
Sda;Y;4;2020-11-04
pawel;Y;4;2020-11-04`
If I use usunPsa("pawel") every line gets removed.
Following code earse my whole csv file instead only one line with given ImiePsa,
What may be the problem there?
I found the problem. row[0] in your code returns the entire row, that means the lines are not parsed correctly. After a bit of reading, I found that csv.reader has a parammeter called delimiter to sepcify the delimiter between columns.
Adding that parameter solves your problem, but not all problems though.
The code that worked for me (just in case you still want to use your original code)
import csv
def usunPsa(ImiePsa):
with open('asd.csv', 'rb') as input, open('schronisko.csv', 'wb') as output:
writer = csv.writer(output)
for row in csv.reader(input, delimiter=';'):
if row[0] == ImiePsa:
writer.writerow(row)
usunPsa("pawel")
Notice that I changed the output filename. If you want to keep the filename the same however, you have to use Hamza Malik's answer.
Just read the csv file in memory as a list, then edit that list, and then write it back to the csv file.
lines = list()
members= input("Please enter a member's name to be deleted.")
with open('mycsv.csv', 'r') as readFile:
reader = csv.reader(readFile)
for row in reader:
lines.append(row)
for field in row:
if field == members:
lines.remove(row)
with open('mycsv.csv', 'w') as writeFile:
writer = csv.writer(writeFile)
writer.writerows(lines)

For Loop on csv file Python

I'm writing a program that runs over a csv file and need to check if one of the lines in the csv file equals to the string iv'e decided but it is not working.
import csv
f= open('myfile.csv')
csv_f = csv.reader(f)
x = 'www.google.com'
for row in csv_f:
if row[index] == x :
print "a"
else:
print row
What is index? You want to check first value for equality, or iterate over each value in row? PS. You should close file at the end, or, better, use with statement.
with open(filename) as f:
csv_file = csv.reader(f)
for row in csv_file:
...

Matching a string with cell in CSV file and returning adjacent cells

I have the following code:
for i in self.jobs:
with open('postcodes.csv', 'rb') as f:
reader = csv.reader(f)
for row in reader:
if row[0] == self.jobs[i][3]:
self.jobs[i].append((row[1],row[2]))
else:
self.jobs[i].append('lat & lng not available)
My problem is this produces "lat & lng not available" for each row in the csv file, I only want to know if it matches give me the info from the adjacent two rows, if it doesn't, give me the 'lat & lng not available'.
See http://pastebin.com/gX5HtJV4 for full code
SSCCE could be as follows:
reader = [('HP2 4AA', '51.752927', '-0.470095'), ('NE33 3GA', '54.991663', '-1.414911'), ('CV1 1FL','52.409463', '-1.509234')]
selfjobs = ['NE33 3AA', 'CV1 1FL', 'HP2 4AA']
latlng = []
for row in reader:
for i in selfjobs:
if i in row[0]:
latlng.append((row[1],row[2]))
else:
latlng.append(('not available','not available'))
print latlng
Following Martineau's help in the comments, this is the code I ended up with:
for i in self.jobs:
job = self.jobs[i]
postcode = job[3]
home = (54.764919,-1.368824)
with open('postcodes.csv', 'rb') as f:
reader = csv.reader(f)
for row in reader:
postcode_csv = row[0]
if postcode in postcode_csv:
job.append((row[1], row[2]))
else:
job.append(home)
I think at least part of the problem is that you actually have the following in your pastebin code:
for i in self.jobs:
with open('postcodes.csv', 'rb') as f:
reader = csv.reader(f)
for row in reader:
if row[0] == self.jobs[i][3]:
self.jobs[i].append((row[1], row[2]))
elif self.jobs[i][3] != row[0]:
self.jobs[i].append("nothing")
However, since theiin thefor i in self.jobsloop is itself alist, it can't be used as a index intoself.jobs like that. Instead, I think it would make more sense to be doing something like the following in the loop:
for job in self.jobs:
with open('postcodes.csv', 'rb') as f:
for row in csv.reader(f):
if row[0] == job[3]:
job.append((row[1], row[2]))
break
else: # no match
job.append("nothing")
...which only indexes the fields of data in the rows read in from the csv file. For efficiency, it stops reading the file as soon as it finds a match. If it ever reads through whole file without finding a match, it appends"nothing"to indicate this, which is what theelseclause of the innerforloop is doing.
BTW, it also seems rather inefficient to open and potentially read through the entirepostcodes.csv file for every entry inself.jobs, so you might want to consider reading the whole thing into a dictionary, once, before executing thefor job in self.jobs:loop (assuming the file's not too large for that).

How to skip the headers when processing a csv file using Python?

I am using below referred code to edit a csv using Python. Functions called in the code form upper part of the code.
Problem: I want the below referred code to start editing the csv from 2nd row, I want it to exclude 1st row which contains headers. Right now it is applying the functions on 1st row only and my header row is getting changed.
in_file = open("tmob_notcleaned.csv", "rb")
reader = csv.reader(in_file)
out_file = open("tmob_cleaned.csv", "wb")
writer = csv.writer(out_file)
row = 1
for row in reader:
row[13] = handle_color(row[10])[1].replace(" - ","").strip()
row[10] = handle_color(row[10])[0].replace("-","").replace("(","").replace(")","").strip()
row[14] = handle_gb(row[10])[1].replace("-","").replace(" ","").replace("GB","").strip()
row[10] = handle_gb(row[10])[0].strip()
row[9] = handle_oem(row[10])[1].replace("Blackberry","RIM").replace("TMobile","T-Mobile").strip()
row[15] = handle_addon(row[10])[1].strip()
row[10] = handle_addon(row[10])[0].replace(" by","").replace("FREE","").strip()
writer.writerow(row)
in_file.close()
out_file.close()
I tried to solve this problem by initializing row variable to 1 but it didn't work.
Please help me in solving this issue.
Your reader variable is an iterable, by looping over it you retrieve the rows.
To make it skip one item before your loop, simply call next(reader, None) and ignore the return value.
You can also simplify your code a little; use the opened files as context managers to have them closed automatically:
with open("tmob_notcleaned.csv", "rb") as infile, open("tmob_cleaned.csv", "wb") as outfile:
reader = csv.reader(infile)
next(reader, None) # skip the headers
writer = csv.writer(outfile)
for row in reader:
# process each row
writer.writerow(row)
# no need to close, the files are closed automatically when you get to this point.
If you wanted to write the header to the output file unprocessed, that's easy too, pass the output of next() to writer.writerow():
headers = next(reader, None) # returns the headers or `None` if the input is empty
if headers:
writer.writerow(headers)
Another way of solving this is to use the DictReader class, which "skips" the header row and uses it to allowed named indexing.
Given "foo.csv" as follows:
FirstColumn,SecondColumn
asdf,1234
qwer,5678
Use DictReader like this:
import csv
with open('foo.csv') as f:
reader = csv.DictReader(f, delimiter=',')
for row in reader:
print(row['FirstColumn']) # Access by column header instead of column number
print(row['SecondColumn'])
Doing row=1 won't change anything, because you'll just overwrite that with the results of the loop.
You want to do next(reader) to skip one row.
Simply iterate one time with next()
with open(filename) as file:
csvreaded = csv.reader(file)
header = next(csvreaded)
for row in csvreaded:
empty_list.append(row) #your csv list without header
or use [1:] at the end of reader object
with open(filename) as file:
csvreaded = csv.reader(file)
header = next(csvreaded)
for row in csvreaded[1:]:
empty_list.append(row) #your csv list without header
Inspired by Martijn Pieters' response.
In case you only need to delete the header from the csv file, you can work more efficiently if you write using the standard Python file I/O library, avoiding writing with the CSV Python library:
with open("tmob_notcleaned.csv", "rb") as infile, open("tmob_cleaned.csv", "wb") as outfile:
next(infile) # skip the headers
outfile.write(infile.read())

Python to insert quotes to column in CSV

I have no knowledge of python.
What i want to be able to do is create a script that will edit a CSV file so that it will wrap every field in column 3 around quotes. I haven't been able to find much help, is this quick and easy to do? Thanks.
column1,column2,column3
1111111,2222222,333333
This is a fairly crude solution, very specific to your request (assuming your source file is called "csvfile.csv" and is in C:\Temp).
import csv
newrow = []
csvFileRead = open('c:/temp/csvfile.csv', 'rb')
csvFileNew = open('c:/temp/csvfilenew.csv', 'wb')
# Open the CSV
csvReader = csv.reader(csvFileRead, delimiter = ',')
# Append the rows to variable newrow
for row in csvReader:
newrow.append(row)
# Add quotes around the third list item
for row in newrow:
row[2] = "'"+str(row[2])+"'"
csvFileRead.close()
# Create a new CSV file
csvWriter = csv.writer(csvFileNew, delimiter = ',')
# Append the csv with rows from newrow variable
for row in newrow:
csvWriter.writerow(row)
csvFileNew.close()
There are MUCH more elegant ways of doing what you want, but I've tried to break it down into basic chunks to show how each bit works.
I would start by looking at the csv module.
import csv
filename = 'file.csv'
with open(filename, 'wb') as f:
reader = csv.reader(f)
for row in reader:
row[2] = "'%s'" % row[2]
And then write it back in the csv file.

Categories