简体   繁体   中英

Looping through lines of text file in python

I have two text files, I want to read it line by line and check if a match occurs and if it occurs then print or else do nothing. But in the following code it checks only for the first line of the first file and checks for the all lines of second for loop file. But I want to check for all lines of the first file as well as second file. I am not sure what mistake I am doing.

with open("changed_commands_from_default_value", "a") \
            as changed_commands_from_default_value, \
     open(command_file, "r") \
            as command_executed_file, \
     open("default_command_values", "r") \
            as default_command_values:
    for default_command in default_command_values:
       for command_executed in command_executed_file:
           only_command = command_executed.split()[0]
           only_default_command = default_command.split()[0]
           if only_command == only_default_command:
               if command_executed != default_command:
                   print("   > The default value " +
                         default_command.rstrip() + " is changed to " +
                         command_executed.rstrip())
                   changed_commands_from_default_value.write(
                       "The default value " + '"' + default_command + '"' +
                       "is changed to " + '"' + command_executed + '"')

My data is like

File 1:

Data1 1
Data2 2
Data3 3
Data4 6
Data5 10

File 2:

Data1 4
Data2 4
Data3 6
....

I would like to have an output like

Data1 is changed from 1 to 4
Data2 is changed from 2 to 4 and so on...

To loop "in parallel" over two iterators, use built-in zip , or, in Python 2, itertools.izip (the latter will require an import itertools at the start of the module, of course).

Eg, change:

        for default_command in default_command_values:
            for command_executed in command_executed_file:

into:

        for default_command, command_executed in zip(
            default_command_values, command_executed_file):

This assumes the two files are indeed "parallel" -- ie, in 1-1 correspondence line by line. If that is not the case, then the simplest approach (unless the files are so huge that your memory can't take it) is to first read one into a dict , then loop over the other one checking in with the dict . So, for example:

    cmd2val = {}
    with open("default_command_values", "r") as default_command_values:
        for default_command in default_command_values:
            cmd2val[default_command.split()[0]] = default_command.strip()

then, separately:

with open(command_file, "r") as command_executed_file:
    for command_executed in command_executed_file:
        only_command = command_executed.split()[0]
        if only_command not in cmd2val: continue   # or whatever
        command_executed = command_executed.strip()
        if command_executed != cmd2val[only_command]:
            # etc, etc, for all output you desire in this case

or vice versa, building the dict from the file that's expected to be smaller, then using it to check, line by line, the file that's expected to be larger.

Just put the reads in the same loop. A minimal working example for two files, named t1.in and t2.in respectively would be:

with open('t1.in', 'r') as f1:
    with open('t2.in', 'r') as f2:
        while True:
        l1, l2 = f1.readline(), f2.readline() # read lines simultaneously

        # handle case where one of the lines is empty 
        # as file line count may differ
        if (not l1) or (not l2): break
        else: 
            # process lines here

This example reads the lines from two files simultaneously and if one of them has fewer lines than the other, min(lines_of_file_1, lines_of_file_2) lines are read.

Here's an implementation of @Alex Martelli's dict suggestion :

#!/usr/bin/env python3
"""Match data in two files. Print the changes in the matched values.

Usage: %(prog)s <old-file> <new-file>
"""
import sys

if len(sys.argv) != 3:
    sys.exit(__doc__ % dict(prog=sys.argv[0]))

old_filename, new_filename = sys.argv[1:]

# read old file
data = {}
with open(old_filename) as file:
    for line in file:
        try:
            key, value = line.split()
            data[key] = int(value)
        except ValueError:
            pass # ignore non-key-value lines

# compare with the new file
with open(new_filename) as file:
    for line in file:
        columns = line.split()
        if len(columns) == 2 and columns[0] in data:
            try:
                new_value = int(columns[1])
            except ValueError:
                continue # ignore invalid lines
            else: # matching line
                value = data[columns[0]]
                if value != new_value: # but values differ
                    print('{key} is changed from {value} to {new_value}'.format(
                        key=columns[0], value=value, new_value=new_value))

Output (for the input from the question)

Data1 is changed from 1 to 4
Data2 is changed from 2 to 4
Data3 is changed from 3 to 6

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM