Skip to content
Advertisement

Is there I can repeat this for a section of rows?

I’m trying to print the rs_id, p_dot and corresponding header for each row after 7 where a cell is occupied on the CSV file.

import csv
with open("CYP2C9.csv",'r') as infile:
    reader = csv.reader(infile, delimiter=",")
    header= next(reader)
    for row in reader:
        rs_id = row[4]
        snp = row[7]
        p_dot = row[1]
        if snp != (""):
            print(rs_id, p_dot, header[7])

I tried defining snp as row[7:8] and printing header [7:8] but output does not match as when I do [7] or [8] individually.

Advertisement

Answer

row[7] is a single element of your list, and will be a string. You can compare this to a string ("") because it is already a string.

row[start:end] is a slice of rows, which is a list. You can’t compare a list to a string, because those are two different things. Instead, you want to compare each element of your slice to that empty string. Consider the following:

import csv
with open("CYP2C9.csv",'r') as infile:
    reader = csv.reader(infile, delimiter=",")
    header= next(reader)
    for row in reader:
        rs_id = row[4]
        p_dot = row[1]
        non_empty_headers = [head for head, cell in zip(header[7:], row[7:]) if cell]
        if non_empty_headers:
            print(rs_id, p_dot, *non_empty_headers)

First, let’s look at the list comprehension:

non_empty_headers = [head for head, cell in zip(header[7:], row[7:]) if cell]

We zip the 7-onwards elements of header and row to iterate over them simultaneously. Then, we select only the header value in our list comprehension, if our cell value from the row is truthy. Remember that non-empty strings are truthy.

if non_empty_headers:
    print(rs_id, p_dot, *non_empty_headers)

Now that we have all headers for non-empty cells, we check if this list is truthy (i.e. it contains at least one element), and print the values in it.

Advertisement