[Tutor] Using 'with open' statementfor reading a file two lines at a time

Cameron Simpson cs at cskk.id.au
Thu Nov 26 22:34:19 EST 2020


On 26Nov2020 20:32, Ken Green <beachkidken at gmail.com> wrote:
>On 11/26/20 8:00 PM, Alan Gauld via Tutor wrote:
>>Post the actual code and any actual error messages in full.
[...]

Ok, a few remarks inline in the code...

># Daily Three Pick Three 99 Combine Test py
># 11/26/2020
>import sys
>filename1 = "Pick_Three_Drawings_File.txt"
>filename2 = "Pick_Three_Drawings_File_Combine.txt"
>file1 = open(filename1, "r")

The "with open" idiom in Python goes like your main with statement:

    with open(filename1) as file1:

which is preferred because it will close the file automatically for you 
(even if there's some exception).

The open above (a) isn't using that idiom and (b) is ignored because you 
open filename1 again below in your "with" statement.

>file2 = open(filename2, "w")
>with open(filename1) as file1:

Same with file2. I'd write:

    with open(filename1) as file1:
        with open(filename2, 'w') as file2:

This has 2 advantages:

The big one is that the with statements arrange to close the files when 
you exit the with statement, reliably and without extra work.

The second one is that we open file2 second. That way if the open of 
file1 (for read) fails, we don't open file2 at all.  And opening file2 
is a destructive action - it overwrites filename2. So we defer that 
until we know opening filename1 went well.

With the "with" statements you can discard the "file1.close()" and 
"file2.close()" below.

>    line1 = file1.readline().strip()
>    line2 = file1.readline().strip()
>    line3 = (line1 + line2)
>    line4 = (line3[ 0: 4] + line3[ 4: 6] + line3[ 6: 8] + line3[ 8: 9] 
>+ line3[ 9:12] + line3[20:21] + line3[21:24])
>    file2.write(line4)

This is the main body of your with statement, which reads the first 2 
lines of the file, combines them and writes to file2.

There's no loop of any kind here, so naturally it happens only once.

The usual idiom for reading lines of text from a file looks like this:

    for line1 in file1:
        ... do something with ine1 ...

Now, you want pairs of lines. So inside the loop you would want to grab 
the next line:

    for line1 in file1:
        ... get line2 ...
        combine and write to file2

which will process the whole file.

Now, you _could_ just go:

    for line1 in file1:
        line2 = file1.readline()
        combine and write to file2

and it would probably work. Alternatively you could look at _how_ the 
for-loop reads the file.

A Python for-loop iterates over what you give it. A text file is an 
"iterable" thing, and when you do that you get lines of text.

So you could pull out the iterator, and use that:

    lines = iter(file1)
    for line1 in lines:
        line2 = next(lines)
        ... combine and write to file2 ...

This works because "lines" is an iterator, which returns lines from the 
file1. If you've got an iterator (of anything) you can get the next 
value with the next() function, which we use to obtain line2.

Cheers,
Cameron Simpson <cs at cskk.id.au>


More information about the Tutor mailing list