如何用Python将文件逐个均匀分配到多个目标文件夹
文件均匀分配到多个目标文件夹的解决思路
我已为此问题困扰两天,希望获取解决思路。我想要实现将源文件夹中的文件逐个移动至5个目标文件夹,并将所有文件均匀分配到这些文件夹中。以下是我目前编写的代码:
import os import shutil #path source = 'C:/Users/folder/Downloads/Files/test' destination = ['C:/Users/folder/Downloads/Files/test1', 'C:/Users/folder/Downloads/Files/test2', 'C:/Users/folder/Downloads/Files/test3', 'C:/Users/folder/Downloads/Files/tes', 'C:/Users/folder/Downloads/Files/test5'] def countItems(): global totalfiles global copiedfiles totalfiles = 0 copiedfiles = 1 for item in os.listdir(source): totalfiles += 1 #get total items countItems() #get Destination while(totalfiles != 0): for dst in destination: for items in os.listdir(source): s = os.path.join(source, items) d = os.path.join(dst, items) if os.path.isfile(d): checker = 'Copy of' filename, filext = os.path.splitext(items) finalF = checker + filename + filext newd = os.path.join(dst, finalF) os.rename(s, newd) countItems() else: shutil.move(s, d) countItems()
现有代码的问题
- 嵌套循环逻辑混乱:多层循环叠加会导致重复处理文件,甚至出现同一文件被多次移动的情况(因为
os.listdir会随着文件移动动态变化) - 全局变量滥用:
countItems依赖全局变量维护状态,容易引发不可预期的逻辑错误 - 重命名逻辑缺陷:
os.rename仅适用于同一磁盘路径的移动,跨磁盘会报错;且命名格式不符合常规习惯 - 未处理子文件夹:直接遍历所有目录项,若源文件夹存在子文件夹,会被当作文件处理引发错误
- 效率低下:每次移动文件后都重新遍历源文件夹统计数量,冗余操作过多
改进后的解决方案
核心思路
- 提前获取源文件夹中所有文件(排除子文件夹)的固定列表,避免循环中目录变化的干扰
- 通过整除和取余计算每个目标文件夹的分配数量,保证文件均匀分布
- 按顺序分配文件,同时处理重名情况,采用通用的重命名格式
改进代码
import os import shutil def get_all_files(source_dir): # 获取源文件夹下所有文件(排除子文件夹) return [f for f in os.listdir(source_dir) if os.path.isfile(os.path.join(source_dir, f))] def distribute_files(source, destinations): files = get_all_files(source) total_files = len(files) num_dests = len(destinations) if total_files == 0: print("源文件夹中没有文件") return # 计算每个目标文件夹的基础分配数和剩余文件数 base_count, remainder = divmod(total_files, num_dests) file_index = 0 for i, dst in enumerate(destinations): # 前remainder个文件夹多分配1个文件,保证均匀 current_count = base_count + (1 if i < remainder else 0) if current_count == 0: continue # 自动创建目标文件夹(不存在则创建) os.makedirs(dst, exist_ok=True) for _ in range(current_count): if file_index >= total_files: break file_name = files[file_index] src_path = os.path.join(source, file_name) dst_path = os.path.join(dst, file_name) # 处理重名文件,采用"文件名(数字).扩展名"格式 counter = 1 while os.path.exists(dst_path): name, ext = os.path.splitext(file_name) dst_path = os.path.join(dst, f"{name} ({counter}){ext}") counter += 1 shutil.move(src_path, dst_path) file_index += 1 # 配置路径 source = 'C:/Users/folder/Downloads/Files/test' destinations = [ 'C:/Users/folder/Downloads/Files/test1', 'C:/Users/folder/Downloads/Files/test2', 'C:/Users/folder/Downloads/Files/test3', 'C:/Users/folder/Downloads/Files/tes', 'C:/Users/folder/Downloads/Files/test5' ] # 执行文件分配 distribute_files(source, destinations)
代码说明
get_all_files:提前获取所有文件列表,避免循环中目录动态变化的问题- 均匀分配逻辑:用
divmod计算基础分配数和余数,前remainder个文件夹各多分配1个文件,确保分配最均匀 - 自动创建文件夹:
os.makedirs配合exist_ok=True,无需手动提前创建目标文件夹 - 重名处理:采用通用的数字后缀格式,避免命名冲突
- 无全局变量:所有状态通过函数参数和局部变量维护,逻辑清晰易维护
内容的提问来源于stack exchange,提问作者Szephy Arulag
相关产品推荐
相关产品推荐

