Best way to access the Nth line of csv file
You can use enumerate
to iterate through the list until you find the right row:
for i, row in enumerate(reader):
if i == line_number:
print("This is the line.")
print(row)
break
You can also use itertools.islice
which is designed for this type of scenario - accessing a particular slice of an iterable without reading the whole thing into memory. It should be a bit more efficient than looping through the unwanted rows.
def get_csv_line(path, line_number):
with open(path) as f:
return next(itertools.islice(csv.reader(f), line_number, None))
But if your CSV file is small, just read the entire thing into a list, which you can then access with an index in the normal way. This also has the advantage that you can access several different rows in random order without having to reset the csv reader.
with open(path) as f:
my_csv_data = list(csv.reader(f))
print(my_csv_data[line_number])
Your solution is actually not that bad. Advancing the file iterator to the line you want is a good approach and is used in many situations like this.
If you want it more concise though, you can use next
and enumerate
with a generator expression:
import csv
the_file = open('path', 'r')
reader = csv.reader(the_file)
N = int(input('What line do you need? > '))
line = next((x for i, x in enumerate(reader) if i == N), None)
print(line)
the_file.close()
The None
in there is what will be returned if the line is not found (N
is too large). You can pick any other value though.
You could also open the file with a with-statement to have it be automatically closed:
import csv
with open('path', 'r') as the_file:
reader = csv.reader(the_file)
N = int(input('What line do you need? > '))
line = next((x for i, x in enumerate(reader) if i == N), None)
print(line)
If you really want to cut down on size, you could do:
from csv import reader
N = int(input('What line do you need? > '))
with open('path') as f:
print(next((x for i, x in enumerate(reader(f)) if i == N), None))
The itertools
module has a number of functions for creating specialized iterators — and its islice()
function could be used to easily solve this problem:
import csv
import itertools
N = 5 # desired line number
with open('path.csv', newline='') as the_file:
row = next(csv.reader(itertools.islice(the_file, N, N+1)))
print("This is the line.")
print(row)
P.S. For the curious, my initial response — which also works (arguably better) — was:
row = next(itertools.islice(csv.reader(the_file), N, N+1))