简体   繁体   中英

Pythonic way to break out of loop

Total python beginner here.

I have the following function, which checks if a string derived from certain inputs exists in a text file. It loops through each line of the text file, to see if an exact match is found.

I have to break out of looping, immediately after the match is found, to avoid needless looping.

Here is the code:

def DateZoneCity_downloaded_previously(Order_Date,ZoneCity):    #   function to check if a given DateZoneCity
                                                                    #   combination had already been completely downloaded
    string_to_match = Order_Date.strftime('%Y/%m/%d') + "-" + ZoneCity[0] + "-" + ZoneCity[1]
    with open(Record_File) as download_status:
        DateZoneCity_exists = False
        for line in download_status:
            if string_to_match in line:
                DateZoneCity_exists = True                      #   if match found, then set "DateZoneCity_exists" to True
                break                                           #   and break out from the [for line in download_status:] loop
        if DateZoneCity_exists: return True
    download_status.close()

I am searching for a more concise, pythonic way to structure the code. Is there anything I can do to make this better? Somehow to eliminate the need for "DateZoneCity_exists" and the second If statement?

This feels like a situation where any would be the best solution:

# Function to check if a given DateZoneCity
def DateZoneCity_downloaded_previously(Order_Date, ZoneCity):
    # Combination had already been completely downloaded
    string_to_match = Order_Date.strftime('%Y/%m/%d') + "-" + ZoneCity[0]
                                                      + "-" + ZoneCity[1]
    with open(Record_File) as download_status:
        return any((string_to_match in line) for line in download_status)

Note that in this case it will return False on negative rather than your current implementation that will return None , also note that it does break out of the looping immediately upon finding a positive result so it does not require looping through the entire file either way.

Just return instead of break :

def DateZoneCity_downloaded_previously(Order_Date,ZoneCity):
    """Check if a given DataZoneCity combination had already been downloaded."""
    string_to_match = Order_Date.strftime('%Y/%m/%d') + "-" + ZoneCity[0] + "-" + ZoneCity[1]
    with open(Record_File) as download_status:
        for line in download_status:
            if string_to_match in line:
                return True
    return False  # No match found.

Depending on how big your text file is, you can read it into a string, and just use that (easier and often faster than reading and checking line per line):

if string_to_match in open(Record_File).read():
    return True

In your example:

def DateZoneCity_downloaded_previously(Order_Date,ZoneCity):                   
    string_to_match = Order_Date.strftime('%Y/%m/%d') + "-" + ZoneCity[0] + "-" + ZoneCity[1]
    if string_to_match in open(Record_File).read():
        return True

You don't have to put a for loop here, See the updated code.

def DateZoneCity_downloaded_previously(Order_Date,ZoneCity):
    """Check if a given DataZoneCity combination had already been downloaded."""
    string_to_match = Order_Date.strftime('%Y/%m/%d') + "-" + ZoneCity[0] + "-" + ZoneCity[1]
    with open(Record_File) as download_status:
        if string_to_match in download_status.read():
            return True
    return False  # No match found.

If record_file is small then you can use in directly with if statement like:-

def DateZoneCity_downloaded_previously(Order_Date,ZoneCity):                   
    string_to_match = Order_Date.strftime('%Y/%m/%d') + "-" + ZoneCity[0] + "-" + ZoneCity[1]
    if string_to_match in open(Record_File).read():
        return True  

while if record_file is large then you have to iterate through each line for finding a match like:-

def DateZoneCity_downloaded_previously(Order_Date, ZoneCity):
    string_to_match = Order_Date.strftime('%Y/%m/%d') + "-" + ZoneCity[0]  + "-" + ZoneCity[1]
    with open(Record_File) as download_status:
        return is_empty((string_to_match in line) for line in download_status)  

because reading line by line will save storage memory used for saving line.

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