遍历 Python 中的目录树
Iterating through a directory tree in Python
我有一组数据存储在目录树中。给定日期的数据在一个带有日期名称的文件夹中(例如 01 表示第一天,14 表示一个月中的第十四天等),给定月份的所有日期的文件夹都存储在每月文件夹(编号 01 到 12)和所有月份文件夹都在年度文件夹中(在我的例子中是 2014 年、2015 年和 2016 年)。所有这些都在另一个文件夹中。
我已经定义了 3 个函数,它们通过使用 for 迭代器和 os.listdir()(但执行有些不同的操作):
for e in os.listdir(os.curdir):
if e.endswith(refer[-4:]:
#Performs operations (GDAL related)
在程序的早期,我让用户输入某些参数,包括顶级文件夹(通过 os.curdir 输入到函数中)和参考文件 (存储在 refer 变量中)。函数 return 变量 arr 存储在 out_arr 中。如果用户想要遍历所有数据,我有这行代码调用正确的函数并深入目录树:
elif param_vrsta == "dr" and param_obdobje == "v":
for dd in os.listdir(os.curdir):
for aa in os.listdir(dd):
for kk in os.listdir(aa):
out_arr = krog1()
有几个 elifs 在前后深入一层或两层或三层并调用三个函数之一。
但我一直收到错误消息:
FileNotFoundError: [WinError 3] Path could not be found: '01'
在
for kk in os.listdir(aa):
行。
最终目标是能够选择对一个文件夹(一天)、一个月(最多 31 个数据文件夹)、一年(12 个文件夹,最多 31 个数据文件夹)或仅对所有数据和每次都有功能工作。
我是不是遗漏了一些语法错误(或添加了太多行),还是我一开始就以错误的方式解决了这个问题?
我不会说你做错了什么。我认为有一种更简单的方法。
考虑一下这个文件夹结构,与您拥有的相比被截断了。
每个最低级别的文件夹只包含一个名为 data.txt 的文件。
将 Path
设置为顶级路径名后,您可以获得该路径下文件的各个子集的迭代器。
>>> from pathlib import Path
>>> path = Path('temp/')
所有文件:
>>> list(path.glob('*/*/*'))
[WindowsPath('temp/01/01/data.txt'), WindowsPath('temp/01/02/data.txt'), WindowsPath('temp/02/01/data.txt'), WindowsPath('temp/02/02/data.txt'), WindowsPath('temp/03/01/data.txt'), WindowsPath('temp/03/02/data.txt')]
2 月的所有文件:
>>> list(path.glob('02/*/*'))
[WindowsPath('temp/02/01/data.txt'), WindowsPath('temp/02/02/data.txt')]
该月第二天的所有文件:
>>> list(path.glob('*/02/*'))
[WindowsPath('temp/01/02/data.txt'), WindowsPath('temp/02/02/data.txt'), WindowsPath('temp/03/02/data.txt')]
2 月第二天的所有文件:
>>> list(path.glob('02/02/*'))
[WindowsPath('temp/02/02/data.txt')]
编辑:补充:
from pathlib import Path
top_path = input('Please input the full name of the top path:')
path = Path(top_path)
year = input('What year do you want to consider? (Enter * for all years)')
month = input('What month do you want to consider? (Enter * for all months)')
day = input('What day do you want to consider? (Enter * for all days)')
for item in path.glob('{}/{}/{}'.format(year, month, day)):
<do something with item here>
我认为您应该认真考虑 Bill Bell 的回答方法,但为了完整起见,以下是(我认为)导致错误的原因:os.listdir returns 不合格的文件名,因此,当您深入研究目录层次结构时,您需要一路指定每个目录。
像这样:
for year_dir in os.listdir(os.curdir):
year_dir = os.path.join(os.curdir, year_dir)
for month_dir in os.listdir(year_dir):
month_dir = os.path.join(os.year_dir, month_dir)
for day_dir in os.listdir(month_dir):
...
备选方案:
- 使用 glob.glob() 而不是 os.listdir():glob 确实限定了文件名
- 使用递归 glob,可能与 pathlib.Path 结合使用(如 Bill Bell 的回答)
- 使用os.walk()
我有一组数据存储在目录树中。给定日期的数据在一个带有日期名称的文件夹中(例如 01 表示第一天,14 表示一个月中的第十四天等),给定月份的所有日期的文件夹都存储在每月文件夹(编号 01 到 12)和所有月份文件夹都在年度文件夹中(在我的例子中是 2014 年、2015 年和 2016 年)。所有这些都在另一个文件夹中。
我已经定义了 3 个函数,它们通过使用 for 迭代器和 os.listdir()(但执行有些不同的操作):
for e in os.listdir(os.curdir):
if e.endswith(refer[-4:]:
#Performs operations (GDAL related)
在程序的早期,我让用户输入某些参数,包括顶级文件夹(通过 os.curdir 输入到函数中)和参考文件 (存储在 refer 变量中)。函数 return 变量 arr 存储在 out_arr 中。如果用户想要遍历所有数据,我有这行代码调用正确的函数并深入目录树:
elif param_vrsta == "dr" and param_obdobje == "v":
for dd in os.listdir(os.curdir):
for aa in os.listdir(dd):
for kk in os.listdir(aa):
out_arr = krog1()
有几个 elifs 在前后深入一层或两层或三层并调用三个函数之一。
但我一直收到错误消息:
FileNotFoundError: [WinError 3] Path could not be found: '01'
在
for kk in os.listdir(aa):
行。 最终目标是能够选择对一个文件夹(一天)、一个月(最多 31 个数据文件夹)、一年(12 个文件夹,最多 31 个数据文件夹)或仅对所有数据和每次都有功能工作。 我是不是遗漏了一些语法错误(或添加了太多行),还是我一开始就以错误的方式解决了这个问题?
我不会说你做错了什么。我认为有一种更简单的方法。
考虑一下这个文件夹结构,与您拥有的相比被截断了。
每个最低级别的文件夹只包含一个名为 data.txt 的文件。
将 Path
设置为顶级路径名后,您可以获得该路径下文件的各个子集的迭代器。
>>> from pathlib import Path
>>> path = Path('temp/')
所有文件:
>>> list(path.glob('*/*/*'))
[WindowsPath('temp/01/01/data.txt'), WindowsPath('temp/01/02/data.txt'), WindowsPath('temp/02/01/data.txt'), WindowsPath('temp/02/02/data.txt'), WindowsPath('temp/03/01/data.txt'), WindowsPath('temp/03/02/data.txt')]
2 月的所有文件:
>>> list(path.glob('02/*/*'))
[WindowsPath('temp/02/01/data.txt'), WindowsPath('temp/02/02/data.txt')]
该月第二天的所有文件:
>>> list(path.glob('*/02/*'))
[WindowsPath('temp/01/02/data.txt'), WindowsPath('temp/02/02/data.txt'), WindowsPath('temp/03/02/data.txt')]
2 月第二天的所有文件:
>>> list(path.glob('02/02/*'))
[WindowsPath('temp/02/02/data.txt')]
编辑:补充:
from pathlib import Path
top_path = input('Please input the full name of the top path:')
path = Path(top_path)
year = input('What year do you want to consider? (Enter * for all years)')
month = input('What month do you want to consider? (Enter * for all months)')
day = input('What day do you want to consider? (Enter * for all days)')
for item in path.glob('{}/{}/{}'.format(year, month, day)):
<do something with item here>
我认为您应该认真考虑 Bill Bell 的回答方法,但为了完整起见,以下是(我认为)导致错误的原因:os.listdir returns 不合格的文件名,因此,当您深入研究目录层次结构时,您需要一路指定每个目录。
像这样:
for year_dir in os.listdir(os.curdir):
year_dir = os.path.join(os.curdir, year_dir)
for month_dir in os.listdir(year_dir):
month_dir = os.path.join(os.year_dir, month_dir)
for day_dir in os.listdir(month_dir):
...
备选方案:
- 使用 glob.glob() 而不是 os.listdir():glob 确实限定了文件名
- 使用递归 glob,可能与 pathlib.Path 结合使用(如 Bill Bell 的回答)
- 使用os.walk()