循环一个目录,但从最后开始?

时间:2021-04-22 21:58:27

标签: python-3.x

我有一个包含许多子目录的目录,每个子目录都遵循相同的命名约定;当天的日期。今天做了一个文件夹:2021-04-22

我偶尔需要浏览这些目录并从中读取文件,但是一旦我阅读了它,我就不需要再读了。

li = []
for root, dirs, files in os.walk(path):
    for f in files:
        li.append(f)

列表显示了读取文件的顺序,这是一个字母(数字?)顺序。我知道由于命名约定,最新的文件将位于底部。

如何从“结束”而不是“开始”开始我的 for 循环?

如果可以的话,我会在满足我的条件时退出循环,否则,从最后开始有什么意义?

编辑:我原来的命名约定打错了。是 YYYY-MM-DD 谢谢@null

3 个答案:

答案 0 :(得分:4)

要在 python 中反转任何可迭代或迭代器,请在 reversed() 中将其扭曲。

在您的代码中:

li = []
for root, dirs, files in os.walk(path):
    for f in reversed(files):
        li.append(f)

答案 1 :(得分:2)

假设你有这个目录树:

.
├── 1
│   ├── a
│   │   ├── 03-01-2021
│   │   └── 04-22-2021
│   ├── b
│   │   └── 04-21-2021
│   └── c
├── 2
│   ├── a
│   │   └── 05-01-2020
│   ├── b
│   └── c
│       └── 01-01-1966
└── 3
    ├── a
    │   ├── 12-15-2001
    │   └── 12-15-2001_blah
    ├── b
    └── c

您可以将 pathlib 与递归 glob 结合使用来获取您的目录。然后使用正则表达式将日期模式反转为 YYYY-MM-DDISO 8601 格式并以相反的方式排序:

import re
from pathlib import Path 

p=Path('/tmp/test/')

my_glob='**/[0-9][0-9]-[0-9][0-9]-[0-9][0-9][0-9][0-9]*'
my_regex=r'.*/(\d{2})-(\d{2})-(\d{4}).*'
for pa in sorted(
            [pa for pa in p.glob(my_glob) if pa.is_dir()], 
            key=lambda pa: re.sub(my_regex,r'\3-\2-\1', str(pa)), reverse=True):
    print(pa)

打印:

/tmp/test/1/a/04-22-2021
/tmp/test/1/b/04-21-2021
/tmp/test/1/a/03-01-2021
/tmp/test/2/a/05-01-2020
/tmp/test/3/a/12-15-2001_blah
/tmp/test/3/a/12-15-2001
/tmp/test/2/c/01-01-1966

'**/*' 的 glob 使搜索递归并添加:

**/[0-9][0-9]-[0-9][0-9]-[0-9][0-9][0-9][0-9]*

将只返回与该命名模式匹配的文件和目录。通过添加测试 if pa.is_dir(),我们只查看目录——而不是文件。

正则表达式:

my_regex=r'.*/(\d{2})-(\d{2})-(\d{4})/'
re.sub(my_regex,r'\3-\2-\1', str(pa))

删除日期以外的所有内容并将其反转为 ISO 8601 以用于传递给 sorted 的密钥。


您要求返回的默认订单文件。 通常文件是从最旧到最新的广度优先。也就是说,它取决于操作系统和实现。


您更新了您的文件确实具有 YYYY-MM-DD 命名约定的问题。如果是这样,只需更改或删除正则表达式。相同的基本方法处理两者。

答案 2 :(得分:1)

由于 files 是一个列表,您可以使用扩展列表切片来反转列表:

li = []
for root, dirs, files in os.walk(path):
    for f in files[::-1]:
        li.append(f)