簡體   English   中英

有沒有比多個 FOR 循環和 IF 語句更有效的方法?

[英]Is there a more efficient way instead of multiple FOR loops and IF statements?

我有以下代碼片段:

for item1 in filesName :
    for item2 in finalName :
        if item1.split('.',1)[0].split('--', 1)[0] == item2.split('.',1)[0].split('--', 1)[0] :
            for eachFile in os.listdir(src) :
                if eachFile == item1 :
                
                    # rename files
                    os.rename(os.path.join(src, item1), os.path.join(src, item2))

                    # move files
                    shutil.move(os.path.join(src, item2), os.path.join(dst, item2))
            
                else :
                    logger.error(error_message)
                    raise ValueError(error_message)

FilesName = ['01-01-2001 Active File Name.xlsx', '01-01-2001 Inactive File Name.xlsx']

FinalName = ['01-01-2001 Active File Name--CORRECTION1.xlsx']

它打算做的是重命名現有文件以防更正-例如,我有一個名為“文件名.xlsx”的文件,但我想將其重命名為“文件名--CORRECTION1.xlsx”-它匹配文件彼此並重命名。

代碼按預期工作,但是我有限的經驗告訴我,我使用了太多的 FOR 循環和 IF 語句,並且可能有更好的方法 [性能方面] 來做到這一點。

那么我的問題是什么 -有更好的解決方案嗎?

FilesName = ['01-01-2001 Active File Name.xlsx', '01-01-2001 Inactive File Name.xlsx']
FinalName = ['01-01-2001 Active File Name--CORRECTION1.xlsx']

# Helper function to clean up the splitting
get_base_name = lambda x: x.split('.',1)[0].split('--', 1)[0]

# Remove the two first loops by checking for base name matches
# using set intersection
filesName_base = {get_base_name(x) for x in FilesName}
finalName_base = {get_base_name(x) for x in FinalName}
files_to_change_base = filesName_base.intersection(finalName_base)

# Potential candidates of files to be changed
files_to_change = [x for x in FilesName if get_base_name(x) in files_to_change_base]

# No need to call this on each iteration of the inner loop
files_in_dir = set(os.listdir(src))

for file_to_change in files_to_change:
    if file_to_change in files_in_dir:
        # rename files
        os.rename(os.path.join(src, item1), os.path.join(src, item2))
        # move files
        shutil.move(os.path.join(src, item2), os.path.join(dst, item2))

    else :
        logger.error(error_message)
        raise ValueError(error_message)

編輯:通過僅循環一次並檢查文件是否在目錄中來刪除另一個 for 循環。 files_in_dir被移動到一個集合中,因為集合成員資格是一個 O(1) 操作,而不是 O(n)。

絕對不需要遍歷目錄中的所有文件來找出具有特定名稱的文件是否已經存在。

如果我完全可以猜到您實際上要完成的工作,那么編寫新文件的代碼當前可能看起來像

### FIXME: don't overwrite if outputfile exists
with open(outputfile, "w") as output:
    output.write(data)

你會把它改成,比如說,

idx = 1
# base is outputfile without .xslx
base = outputfile[:-5]
while os.path.exists(outputfile):
    outputfile = "%s--CORRECTION%i.xlsx" % (base, idx)
    idx += 1

with open(outputfile, "w" ...

循環在--CORRECTION之后更新數字,直到它落在現有文件尚未占用的數字上。 (如果您刪除該序列中間某處的文件,代碼顯然會重用該編號,而不是遞增超過編號序列中最后一個編號的文件。)

也許更好的設計完全是使用版本控制。 用不那么腦殘的東西替換 Excel 文件格式也將極大地簡化您的生活。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM