Pythonic打破循环的方法

时间:2016-06-10 04:12:18

标签: python loops python-3.x

这里的蟒蛇初学者。

我有以下函数,它检查文本文件中是否存在从某些输入派生的字符串。它循环遍历文本文件的每一行,以查看是否找到完全匹配。

我必须在找到匹配后立即退出循环,以避免不必要的循环。

以下是代码:

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()

我正在寻找一种更简洁,更pythonic的方式来构造代码。有什么办法可以让它变得更好吗?不知何故,以消除" DateZoneCity_exists"和第二个If语句?

5 个答案:

答案 0 :(得分:6)

这感觉就像any是最佳解决方案的情况:

# 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)

请注意,在这种情况下,它将返回False而不是当前实现将返回None,同时请注意,它会在找到肯定结果时立即突破循环,因此它无论如何都不需要遍历整个文件。

答案 1 :(得分:4)

return代替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.

答案 2 :(得分:3)

根据文本文件的大小,您可以将其读取为字符串,然后使用它(比读取和检查每行的行更容易且通常更快):

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

在你的例子中:

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

答案 3 :(得分:2)

您不必在此处输入for循环,请参阅更新后的代码。

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.

答案 4 :(得分:0)

如果record_file很小,那么您可以直接使用in if语句,如: -

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  

如果record_file很大,那么你必须遍历每一行才能找到匹配项: -

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)  

因为逐行读取会节省用于保存行的存储空间。