如何按排序顺序遍历字典键值

3

我正在读取一个cfg文件,并针对每个部分接收一个字典。例如:

配置文件:

[General]
parameter1="Param1"
parameter2="Param2"

[FileList]
file001="file1.txt"
file002="file2.txt" ......

我有一个名为section的字典,其中存储了FileList部分的内容。在这个例子中,我可以通过test = section["file001"]访问"file1.txt",因此test == "file1.txt"。要依次访问FileList中的每个文件,可以尝试以下方法:

for i in range(1, (number_of_files + 1)):
    access_key = str("file_00" + str(i))
    print(section[access_key])

这是我的当前解决方案,但我一点也不喜欢。首先,在 Python 中它看起来有点混乱,而且当配置中列出超过9个文件时,我也会面临问题。
我也可以这样做:
for i in range(1, (number_of_files + 1)):
    if (i <= 9):
        access_key = str("file_00" + str(i))
    elif (i > 9 and i < 100):
        access_key = str("file_0" + str(i))
    print(section[access_key])

但我不想从那个开始,因为情况会变得更糟。所以我的问题是:有没有一种适当且相对清洁的方式按顺序遍历所有文件名?我绝对需要循环,因为我需要对每个文件执行一些操作。


1
请告诉我我所做的修改是否可接受。 - Mad Physicist
3个回答

2
使用零填充生成文件编号(例如,请参见此SO问题答案:https://dev59.com/g3RC5IYBdhLWcg3wUfN2#339013)。这样,您就不必编写自己的数字翻转逻辑 - 您可以使用内置的Python功能来完成。如果您正在使用Python 3,我还建议您尝试使用f-strings(链接上面提供了其中一种解决方案)。它们非常棒!

这正是我正在寻找的,更加方便。谢谢! - user44791
这听起来不对。您仍在为包含3个键的文件迭代999个键。如果用户错过一个数字或意外添加或跳过一个数字,您可能会错过键。 - Mad Physicist
这取决于 OP 所打算做的事情。我的答案认为 OP 真的需要迭代可能键列表,并回答如何这样做。我同意你的观点,但认为那应该是一个单独的问题。 - bob

1

如果我们可以假设文件编号有三位数字,那么您可以采取以下方法来实现零填充。以下所有方法都会返回“015”。

i = 15

str(i).zfill(3)
# or
"%03d" % i 
# or
"{:0>3}".format(i)
# or
f"{i:0>3}"

感谢您的解决方案,链接https://dev59.com/g3RC5IYBdhLWcg3wUfN2#339013中的答案也使用了这种方法。 - user44791

0

首先要看看实际拥有的键,而不是猜测可能是什么。您需要过滤掉与您模式匹配的那些键,并按数字部分进行排序。

keys = [key for key in section.keys() if key.startswith('file') and key[4:].isdigit()]

您可以添加其他条件,例如len(key) > 4,或完全放弃条件。您还可以考虑学习正则表达式以使检查更加优雅。

为了对名称进行排序而不必考虑填充,您可以尝试以下操作:

keys = sorted(keys, key=lambda s: int(s[4:]))

你也可以尝试使用像natsort这样的库,它会更普遍地处理自定义排序键。

现在,你可以迭代键并做任何你想做的事情:

for key in sorted((k for k in section if k.startswith('file') and k[4:].isdigit()), key=lambda s: int(s[4:])):
    print(section[key])

下面是一个使用 renatsort 的解决方案示例:

import re
from natsort import natsorted

pattern = re.compile(r'file\d+')
for key in natsorted(k for k in section if pattern.fullmatch(k)):
    print(section[key])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接