Troubleshooting Nested Loops in Python: Unexpected Output Explained

  • Context: Python 
  • Thread starter Thread starter cepheid
  • Start date Start date
  • Tags Tags
    Loops Python Stupid
Join the discussion
Ask a follow-up here, or get your own question answered by working scientists, mathematicians and engineers — people, not an autocomplete.
Real named experts · corrections over time · the nuance an AI answer skips
7 replies · 3K views
Messages
5,197
Reaction score
38
My code isn't working, and the reason seems to be because nested for loops in python don't work according to my expectations. If I have some code like this:

Code:
f1 = open('name_of_file1.txt', 'r')
f2 = open('name_of_file2.txt', 'r')

for line1 in f1:
    #stuff at this level should happen once for every line in file1. Right?
    print line1
    for line2 in f2:
            #stuff at this level should happen once for every line in file2. Right?
            print line2

My expectation for the output:

Code:
line 1 from file1
.
.
.
(all lines from file2 here)
.
.
.
line 2 from file1
.
.
.
(all lines from file2 here)
.
.
.
line 3 from file1
.
.
.
(all lines from file2 here)
.
.
.
et cetera

The output that I ACTUALLY get:

Code:
line 1 from file1
.
.
.
(all lines from file2 here)
.
.
.
(all remaining lines from file1 in sequence)

Huh?
 
Physics news on Phys.org
It looks like when the program tries to print the lines from file2 the second time, it's still "stuck" at the end of file2 from the first time.

Try opening file2 inside the outer loop right before you start to read lines from it. Then close it after the inner loop (but before the outer loop ends).
 
cepheid said:
#stuff at this level should happen once for every line in file2. Right?
Wrong.

Python can't read your mind. How is it to know that you want file2 rewound?

Issue a file2.seek(0) command before the start of your inner loop to rewind the file to the start. Unlike jtbell's suggestion, you only need one open command for file2 if you rewind via seek(). Opens are expensive. Seeks are relatively cheap.
 
D H said:
Wrong.

Python can't read your mind. How is it to know that you want file2 rewound?

Issue a file2.seek(0) command before the start of your inner loop to rewind the file to the start. Unlike jtbell's suggestion, you only need one open command for file2 if you rewind via seek(). Opens are expensive. Seeks are relatively cheap.

Got it. And yes, this turned out to be the story. Thanks to both of you for the help.
 
D H said:
Issue a file2.seek(0) command before the start of your inner loop to rewind the file to the start.

Yes, that's better than my idea. I didn't know whether python had some sort of "rewind" operation, so I played it safe with the close / (re)open trick.
 
Same here - problem was obvious, I just wasn't sure how to implement it in Python other than by close/save. But JT was faster :smile:
 
I would do something like this:
Code:
[i]#!/usr/bin/env python2[/i][/color]
[i]# -*- coding: utf-8 -*-[/i][/color]
[b]from[/b][/color] [b]__future__[/b][/color] [b]import[/b][/color] print_function
[b]from[/b][/color] [b]__future__[/b][/color] [b]import[/b][/color] unicode_literals

[b]with[/b][/color] open[/color]('file1.txt'[/color], 'r'[/color]) [b]as[/b][/color] f1:
    [b]for[/b][/color] line [b]in[/b][/color] f1.[/color]readlines():
        [b]print[/b][/color](line)
        [b]with[/b][/color] open[/color]('file2.txt'[/color], 'r'[/color]) [b]as[/b][/color] f2:
            [b]for[/b][/color] line [b]in[/b][/color] f2.[/color]readlines():
                [b]print[/b][/color](line)