pythondata-analysisbreaktxt

How To Read A Text File, Stop After Encountering A Certain Value And Continue Reading


I have a text file with this format:

0   -82.871 2.52531 36.64   138 96.05
0   -76.1014    2.52577 35.36   137 83.9
0   -76.1869    5.57562 35.36   137 62.8
0   -18.1623    -11.6886    386.08  411 200.9
0   -4.62234    -4.91846    325.92  364 252.2
0   -2.52609    -1.63149    325.92  364 85.4
0   -2.52609    -1.63149    112.16  197 48.4
0   -18.1623    -4.91846    -54.24  67  69.55
0   -18.1623    -4.91846    386.08  411 64.55
12345678  1
12345678  2
2   25.2279 -72.3226    48.16   147 221.55
2   28.7109 -70.2263    48.16   147 1587.7
2   76.1009 -63.4562    46.88   146 110.35
2   31.9979 -65.5526    48.16   147 1601.8
2   35.4805 -63.4559    48.16   147 310.25
2   31.9979 -58.7826    49.44   148 492.8
2   35.4805 -56.6859    46.88   146 42.6
2   1.63117 -43.1461    73.76   167 54.55
2   4.91818 -38.4723    76.32   169 75.4

I have written a program that skips the entire header with line = raw_dat.readlines()[7:] and reads the entire file until it encounters the magic_number and breaks the loop:

file = 'Runnumber169raw10.txt'
magic_number = '12345678'

event1 = []
x1 = []
y1 = []
z1 = []
tb1 = []
q1 = []
Xnoselection = []
X = []
distanceradius = 0

with open(file, 'r') as raw_dat:
    line = raw_dat.readlines()[7:]
    
    for lines in line:
        lines.split()
        print(lines)
        if lines.split()[0] == magic_number:
            break

The break statement stops the loop and the values corresponding to column values of 0 are stored. But I can't figure out a way to continue reading after this break statement, as break essentially terminates the loop. Is there a way to stop the loop, store the data, and continue reading and repeat?


Solution

  • Continue instead break?

    a way to continue reading after this break statement, as break essentially terminates the loop.

    If you want to ignore the lines prefixed with the magic number and jump to the next iteration of the loop, then the easiest statement would be continue.

    There are 2 loop interruption statements:

    1. break: exit a loop prematurely
    2. continue: skip an iteration of a loop

    See also:

    Conditional action (stop, store, continue)

    Is there a way to stop the loop, store the data, and continue reading and repeat?

    When you need to trigger conditional action in a loop, e.g. to save state or change the mode, then use the conditional if and invoke the action as function.

    Example

    The function might be store_lines_for_event to write the lines to a text-file named after the event:

    def store_lines_for_event(collected_lines, event_id):
        filename = 'events_' + str(event_id) + '.txt'
        with open(filename, 'a') as f:
            f.writelines(collected_lines)
    

    The loop can use the function conditionally (if), either having the regular processing in an else branch or using the continue statement.

    Let's start with the if .. else:

    event_id = ''
    collected_lines = []
    for line in lines:
        # the default action that applies to all before
        print("Read line", line)
    
        if line.startswith(magic_number):  # conditional special handling
            store_lines_for_event(collected_lines, event_id)
            event_id = line.replace(magic_number, '').strip()
            collected_lines = []
        else:  # regular handling of lines
            collected_lines.append(line)
    
        # the default action that applies to all afterwards
        print("collected lines in buffer now", len(collected_lines))
    

    This can also be written equivalently without else, but with continue like this:

    event_id = ''
    collected_lines = []
    for line in lines:
        if line.startswith(magic_number):  # conditional special handling
            store_lines_for_event(collected_lines, event_id)
            event_id = line.replace(magic_number, '').strip()
            collected_lines = []
            continue  # directly jump to the next iteration and line and
                      # ignore the following statements of the loop body
    
        # regular handling of lines
        collected_lines.append(line)