-1

So, I have a file and I need to read in from the columns of the file. The column contains frequency of genes as floats. The number of the column to be read in is column_number variable. Then, all of the floats (there are only floats in the column) in that column should be appended to a list. So far I have gotten this far:

def read_column(file_name, column_number):
lines = file_name.readlines()
floats = []
for x in lines:
    floats.append(x.split(" ")[column_number])
return floats

The file is passed in as an argument and does not need to be opened, since the test program creates and opens a temporary file with the genetic frequencies in it.

When I run this code I get the following error:

'str' object has no attribute 'readlines'

What is it that I'm doing wrong?

MisterMiyagi
  • 44,374
  • 10
  • 104
  • 119
Maskurate
  • 21
  • 4
  • 1
    "file is passed in as an argument" Your function expects a ``file_name``. Do you actually pass in a file or just its name/path? – MisterMiyagi Sep 08 '21 at 12:36
  • 1
    I *recommend* passing the file. Let the caller open the file; this make `read_column` easier to test because it will work with *any* file-like object, not just one provided by the `open` function. – chepner Sep 08 '21 at 12:43

1 Answers1

1

Despite the parameter name, the function expects a file-like object, not the name of a file that you would then need to open.

with open(my_file_name) as f:
    x = read_column(f, 3)

This is preferable to redefining the function to take a filename that you open, because your file will work with any file-like object (e.g., io.StringIO), making it easier to test.

In fact, you can make a simple change that will make the function both more memory-efficient (by not reading the entire file into memory at once) and able to work with any iterable (like a list), not just a file-like object.

def read_column(itr, column_number):
    floats = []
    for x in itr:
        floats.append(x.split(" ")[column_number])
    return floats
chepner
  • 497,756
  • 71
  • 530
  • 681