2

I'm a beginner with Python. I tried to solve the problem: "If we have a file containing <1000 lines, how to print only the odd-numbered lines? ". That's my code:

with open(r'C:\Users\Savina\Desktop\rosalind_ini5.txt')as f:
   n=1
   num_lines=sum(1 for line in f)
   while n<num_lines:
         if n/2!=0:
                 a=f.readlines()[n]
                 print(a)
         break
    n=n+2

where n is a counter and num_lines calculates how many lines the file contains. But when I try to execute the code, it says:

"a=f.readlines()[n]
 IndexError: list index out of range"

Why it doesn't recognize n as a counter?

  • What does that `[n]` should mean ? – Cajuu' Oct 12 '16 at 11:25
  • 2
    After your first `for line in f` you have already read the whole file and reached the end. Since you're at the end of the file, `f.readlines()` will return an empty list. You should just read the lines once. – khelwood Oct 12 '16 at 11:29
  • In the tutorials which I read they said that: " If you need to obtain a particular line, you can use a list item index, e.g., f.readlines()[2] returns the third line of the file object f", so I used this construction. – Savina Dimitrova Oct 12 '16 at 11:29
  • What is the alternative of f.readlines() if I want to use a loop? – Savina Dimitrova Oct 12 '16 at 11:31

4 Answers4

2

You have the call to readlines into a loop, but this is not its intended use, because readlines ingests the whole of the file at once, returning you a LIST of newline terminated strings.

You may want to save such a list and operate on it

list_of_lines = open(filename).readlines() # no need for closing, python will do it for you
odd = 1
for line in list_of_lines:
    if odd : print(line, end='')
    odd = 1-odd

Two remarks:

  1. odd is alternating between 1 (hence true when argument of an if) or 0 (hence false when argument of an if),
  2. the optional argument end='' to the print function is required because each line in list_of_lines is terminated by a new line character, if you omit the optional argument the print function will output a SECOND new line character at the end of each line.

Coming back to your code, you can fix its behavior using a

f.seek(0)

before the loop to rewind the file to its beginning position and using the f.readline() (look, it's NOT readline**S**) method inside the loop, but rest assured that proceding like this is. let's say, a bit unconventional...

Eventually, it is possible to do everything you want with a one-liner

print(''.join(open(filename).readlines()[::2]))

that uses the slice notation for lists and the string method .join()

Community
  • 1
  • 1
gboffi
  • 22,939
  • 8
  • 54
  • 85
0

Well, I'd personally do it like this:

def print_odd_lines(some_file):
    with open(some_file) as my_file:
        for index, each_line in enumerate(my_file):  # keep track of the index of each line
            if index % 2 == 1:  # check if index is odd
                print(each_line)  # if it does, print it

if __name__ == '__main__':
    print_odd_lines('C:\Users\Savina\Desktop\rosalind_ini5.txt')

Be aware that this will leave a blank line instead of the even number. I'm sure you figure how to get rid of it.

Cajuu'
  • 1,154
  • 2
  • 19
  • 50
0

This code will do exactly as you asked:

with open(r'C:\Users\Savina\Desktop\rosalind_ini5.txt')as f:
    for i, line in enumerate(f.readlines()):   # Iterate over each line and add an index (i) to it.
        if i % 2 == 0:       # i starts at 0 in python, so if i is even, the line is odd
            print(line)

To explain what happens in your code:

A file can only be read through once. After that is has to be closed and reopened again.

You first iterate over the entire file in num_lines=sum(1 for line in f). Now the object f is empty.

If n is odd however, you call f.readlines(). This will go through all the lines again, but none are left in f. So every time n is odd, you go through the entire file. It is faster to go through it once (as in the solutions offered to your question).

Michel Touw
  • 626
  • 6
  • 15
  • This will print the even lines :) – Cajuu' Oct 12 '16 at 11:34
  • In his code, he starts with `n = 1`. From that, I interpret that he calls the first line what python calls the zeroth line. Therefore, as an answer to his question, this will print what he defines as an odd line number. – Michel Touw Oct 12 '16 at 11:36
0

As a fix, you need to type

f.close()
f = open(r'C:\Users\Savina\Desktop\rosalind_ini5.txt')

everytime after you read through the file, in order to get back to the start.

As a side note, you should look up modolus % for finding odd numbers.

Dmitry Orlov
  • 454
  • 6
  • 14
Andy
  • 263
  • 1
  • 11