我有一个文件夹结构和这样的文件:
- doe-john
- inbox
- 1.
- 2.
- 3.
- sent
- 1.
- 2.
- 3.
- notes
- 1.
- 2.
- 3.
- contacts
- 1.
- 2.
- 3.
- doe-jane
- inbox
- 1.
- 2.
- 3.
- sent
- 1.
- 2.
- 3.
- notes
- 1.
- 2.
- 3.
- contacts
- 1.
- 2.
- 3.
我只想枚举每个主文件夹中inbox
和sent
个文件夹中的文件。我知道如何枚举所有文件:
for root, dirs, files in os.walk(top_level_folder):
for fn in files:
with open(os.path.join(root, fn), 'r') as f:
pass # do something
我认为我会这样做,但我不太确定如何正确地做到这一点:
for root, dirs, files in os.walk(top_level_folder):
for dir in dirs:
if dir.lower() == "inbox" or dir.lower() == "sent":
for fn in files:
with open(os.path.join(root, fn), 'r') as f:
pass # do something
但这仍然只是列举了所有文件。如何仅枚举具有指定文件夹名称的文件夹中的文件?
答案 0 :(得分:3)
您让root
和dirs
感到困惑。 root
是"当前目录"在每个级别; dirs
是在此级别可见的目录列表。
您当前的代码处理每个目录中的所有文件,每个可见子目录一次。您想要的是查看当前目录是inbox
还是sent
,然后才进行处理。
for root, dirs, files in os.walk(top_level_folder):
if root.lower().endswith("inbox") or root.lower().endswith("sent"):
for fn in files:
with open(os.path.join(root, fn), 'r') as f:
pass # do something
您还可以在topdown=True
来电中设置walk
,然后修改要导入的子目录。
for root, dirs, files in os.walk(top_level_folder, topdown=True):
if root != top_level_folder:
# only recurse into level 3+ directories with the desired names
dirs[:] = [d for d in dirs if d in ['inbox', 'sent']]
if root.lower().endswith("inbox") or root.lower().endswith("sent"):
for fn in files:
with open(os.path.join(root, fn), 'r') as f:
pass # do something
但是,我觉得这个选项有点难看(特别是因为你需要在顶级特殊情况下避免跳过/doe-john
等)。在您的特定情况下,由于您只想查看两个目录并且它们只有一个级别,我根本不会使用walk
:
for person in os.listdir(top_level_folder):
inbox = os.path.join(top_level_folder, person, 'inbox')
sent = os.path.join(top_level_folder, person, 'sent')
for file in os.listdir(inbox):
pass # Do something
for file in os.listdir(sent):
pass # Do something
答案 1 :(得分:1)
如果您使用dirs
选项,则可以修改从os.walk()
返回的topdown=True
。根据{{3}}:
当 topdown 为
True
时,调用者可以就地修改 dirnames 列表(可能使用del
或切片分配),并且walk()
只会递归到名称保留在 dirnames 中的子目录中;这可用于修剪搜索,强制执行特定的访问顺序,甚至可以通知walk()
有关调用者在再次恢复walk()
之前创建或重命名的目录。当 topdown 为False
时修改 dirnames 无效,因为在自下而上模式下, dirnames 中的目录是在之前生成的dirpath 本身已生成。