如何从嵌套第二层循环Break后,继续执行第一层与第三层循环?
问题解决思路与代码修改
问题背景
我有一个包含3个子文件夹的文件夹,每个子文件夹内有10个文件。如果不在第一层循环中添加break语句,程序会输出:
[['folderA', 'folderB', 'folderC'], [], [], []]
想要实现的效果是:处理完根目录的子文件夹(即代码中标注的"loop 2"部分)后,不终止第一层循环,继续让第一层循环遍历子目录,同时正常执行第三层循环收集所有文件。
原代码如下:
folderName = [] fileName = [] for add, directory, allfiles in os.walk("path"): #loop one folderName.append([re.sub(r'([^a-zA-Z ]+?)', '', i) for i in directory]) #loop 2 break for name in allfiles: #loop 3 fileName.append(os.path.join(add, name))
问题分析
os.walk的遍历逻辑:第一次迭代返回根目录的信息(根路径、根目录下的子文件夹列表、根目录内的文件),后续迭代依次返回每个子文件夹的信息(此时子文件夹内没有下一级目录,所以directory为空列表)。- 原代码的问题:加
break会直接终止第一层循环,导致第三层循环完全没机会执行;不加break则会在每次迭代时都往folderName里添加目录列表,子文件夹的directory为空,所以出现多余的空列表。
解决方案
方案1:只收集根目录的子文件夹,同时收集所有文件
如果只是想只保留根目录的子文件夹列表,同时收集所有目录下的文件,用一个标记位控制只在第一次迭代时处理folderName,去掉break让第一层循环完整遍历:
import os import re folderName = [] fileName = [] is_first_loop = True for add, directory, allfiles in os.walk("path"): # 仅在第一次遍历(根目录)时处理子文件夹列表 if is_first_loop: folderName.append([re.sub(r'([^a-zA-Z ]+?)', '', i) for i in directory]) is_first_loop = False # 标记为已处理根目录,后续不再添加folderName # 执行文件收集逻辑,遍历所有目录的文件 for name in allfiles: fileName.append(os.path.join(add, name))
修改后效果:
folderName结果为[['folderA', 'folderB', 'folderC']],不会出现多余空列表fileName会包含3个子文件夹里的所有30个文件(如果根目录无文件)
方案2:在处理子文件夹时可中途break,不影响后续循环
如果需要在处理根目录的子文件夹时(即你说的第二层循环),满足某个条件就break终止该部分,但不影响第一层循环继续遍历和第三层循环执行,把列表推导式改成普通循环即可:
import os import re folderName = [] fileName = [] is_first_loop = True for add, directory, allfiles in os.walk("path"): if is_first_loop: cleaned_dirs = [] for dir_name in directory: cleaned_name = re.sub(r'([^a-zA-Z ]+?)', '', dir_name) cleaned_dirs.append(cleaned_name) # 示例:遇到folderB就停止处理子文件夹列表 if cleaned_name == 'folderB': break folderName.append(cleaned_dirs) is_first_loop = False # 正常收集所有文件,不受子文件夹处理循环的break影响 for name in allfiles: fileName.append(os.path.join(add, name))
这种情况下,处理子文件夹的循环中途break后,第一层循环会继续遍历所有子目录,第三层循环也会正常收集所有文件。
内容的提问来源于stack exchange,提问作者yellowAndriod
相关产品推荐
相关产品推荐

