一、问题来源
遍历文件夹是python最常用的操作,比如训练神经网络需要的图片输入、对文件的处理等。近期想编写一个对图像加密所用的exe程序,需要用到加密选中的文件夹中所有的图片,这时我就开始思考:怎么可以使得遍历的速度较快?怎么使得占用的资源较少?
二、遍历方法
1. 递归
递归是我想到的最直接的遍历方法,类似深度搜索。使用python来写函数的递归肯定是比较慢的(当遍历的文件夹深度较深、数量较大时),如果是文件夹较少时可以使用该方法,因为确实很直接。
缺点也很明显,就是需要专门去区分文件夹和你所需要的文件。
另外速度比较慢,循环都是用python写的,相比c语言要慢的多。
当文件数量较大时,需要占用较多的内存。
- import os
- def mywalk(dir):
- for m in os.listdir(dir):
- if m[-4:] == '.bmp':
- file = os.path.join(dir, m)
- print('file: ', file)
- else:
- file = os.path.join(dir, m)
- mywalk(file)
- mywalk('./data/')
2. os.walk+迭代
os.walk是专门针对遍历文件夹中的文件的库,底层代码是C/C++写的,速度要快,示例为os.walk的用法。
- import os
- for root,dirs,files in os.walk(r"./data/"):
- '''
- root: 根目录
- dirs:根目录下的文件夹目录
- files:根目录下的文件目录
- '''
- for file in files:
- print('root: ', root)
- print('dirs: ', dirs)
- print('files: ', files)
结果示例:
- root: ./data/
- dirs: ['log_bmp']
- files: ['20190109_150108_0262_0.80.bmp']
- root: ./data/log_bmp
- dirs: ['20190108', '20190109']
- files: ['20190109_150108_0262_0.80.bmp']
- root: ./data/log_bmp\20190108
- dirs: []
- files: ['20190108_194653_0221_1.13.bmp', '20190108_194657_0262_0.79.bmp']
- root: ./data/log_bmp\20190108
- dirs: []
- files: ['20190108_194653_0221_1.13.bmp', '20190108_194657_0262_0.79.bmp']
- root: ./data/log_bmp\20190109
- dirs: []
- files: ['20190109_150108_0262_0.80.bmp']
以上我们解决了遍历速度的问题,还需要解决文件过大的问题。
参考:https://www.cnblogs.com/wj-1314/p/8490822.html
确定了我们使用生成器的表达式:在for循环的基础上添加一个小括号。示例如下:
- import os
- path_collection = (os.path.join(root,fn) for root,dirs,files in os.walk('./data') for fn in files)
- for m in path_collection:
- print(m)
划重点:
生成器:一边循环一边计算,可以节省内存
三、总结
1. 尽量使用python自带的库,因为底层是用C/C++写的,速度比较快
2. 尽量使用生成器代替列表,这样可以节省内存
3. 在神经网络的训练中,加载数据库就是使用了生成器的方法,边加载边计算
有兴趣可以看一下:https://blog.csdn.net/sinat_42239797/article/details/90641659