Home > front end >  How can I pull a single row from CSV file?
How can I pull a single row from CSV file?

Time:10-19

I'm aware that there are similar questions that have already been answered, but I haven't found any that don't recommend using pandas, lists, or enumerate, all of which I cannot use.

How would I go about printing a specific row from a CSV file using a function?

import csv
FILE = 'internet_access.csv'
def read_csv(FILE, count):

 with open(FILE, 'r') as infile:
    internet_line = csv.reader(infile, delimiter=',')
    count = 0
    internet_list = []
    for row in internet_line:
        headers = row.pop(0)
    print(row)
 return read_csv

totals = read_csv(FILE, 7)
print(totals)

This is all I have so far and it prints out all the rows in the file. I just want to print out whatever row I ask it to print out so I can work with the data in the file. I did remove the headers already with pop, so all that's left is the raw data.

I've tried to add many different if statements to the for loop, and even another for loop within the for loop but I always get all the rows printed back. Is there any way to do this without using pandas, lists, or enumerate?

CodePudding user response:

Here's a function that pulls a specific line from a csv file:

def read_line(csv, line_num):
    with open(csv,'r') as f:
        for i in range(line_num   1):
            line = f.readline()
    return line

You could then call this function like so:

FILE = 'internet_access.csv'
print(read_line(FILE, 7))

CodePudding user response:

You simply have to read and skip the lines until the desired line. You can do this using csv.reader and next():

import csv

def read_csv_line(file_path, line_num):
    
    with open(file_path, "r") as file:
        
        reader = csv.reader(file)

        for _ in range(line_num-1):
            next(reader)
        return next(reader)

        # or using a list comprehension:
        # return [next(reader) for _ in range(line_num)][-1]

row = read_csv_line("internet_access.csv", 7)

Or, if you do not want to have the line parsed, you can considered the example below:

def read_line(file_path, line_num):
    
    with open(file_path, "r") as file:
        
        for _ in range(line_num-1):
            next(file)

        return next(file)

line = read_line("internet_access.csv", 7)

Alternatively, if you can use itertools.islice, then you could also do something like this:

import csv
from itertools import islice

def read_csv_line(file_path, line_num):
    
    with open(file_path, "r") as file:
        
        reader = csv.reader(file)
        
        for row in islice(reader, line_num-1, line_num):
            return row
    
row = read_line("internet_access.csv", 7)

Another option would be to use linecache.getline which returns the desired line as a string:

import linecache

line = linecache.getline("internet_access.csv", 7).rstrip("\n")
# linecache.clearcache()

You could do something like this to parse it using the csv package:

import csv
import io
import linecache

def read_csv_line(file_path, line_num):

    line = linecache.getline(file_path, line_num)
    # linecache.clearcache()

    reader = csv.reader(io.StringIO(line))
    return next(reader)
        
row = read_line("internet_access.csv", 7)

However, it's important to notice that linecache keeps the file content in the memory until you clear the cache with linecache.clearcache(). Unless you are accessing the same file over and over again, I would suggest using one of the approaches not using linecache.

CodePudding user response:

I would use the csv module to read the file because it can handle CSV records that span more the one physical line in the file. So, assuming you're counting lines from 1, you could get the 7th line like this:

import csv


FILE_NAME = 'internet_access.csv'

def read_csv_line(filename, count):
    with open(filename, 'r', newline='') as infile:
        for i, line in enumerate(csv.reader(infile, delimiter=','), start=1):
            if i == count:
                return line

totals = read_csv_line(FILE_NAME, 7)
print(totals)

I also think you should read and start following PEP 8 - Style Guide for Python Code if you're going to be writing much Python code.

CodePudding user response:

Here's a function that removes the header row, uses enumerate to work out which row is the target, then returns that row parsed as a list.

import csv

def read_csv(path, target):
    with open(path, 'r', newline="") as infile:
        reader = csv.reader(infile)
        next(reader)  # Ignore headers
        for i, row in enumerate(reader, start=1):
            if i == target:
                return row
    raise ValueError(f"Cannot read row {target} from {path}")

print(read_csv('internet_access.csv', 7))

This assumes that the CSV has a header row. If it might not have one, there should probably be a try/except block around the next(reader) line.

  • Related