字典推导中的动态if语句

0 投票
2 回答
929 浏览
提问于 2025-04-17 16:29

我正在用一种叫做字典推导的方式来创建一个字典,这个字典的键是mp3文件的名字,而值是这些文件的路径。

我这样做:

for root, dirs, files in os.walk(rootDir, topdown='true'):
    source_files = {filename:root for filename in files if os.path.splitext(filename)[1].lower() == '.mp3'}
    # more code
    # ...
    # ...

more code部分,我对源文件进行了更多的处理。现在,我想对任何图片文件(比如.gif、.jpeg等)重复这个处理逻辑。

所以我可以这样做:

for root, dirs, files in os.walk(rootDir, topdown='true'):
    source_files = {filename:root for filename in files if os.path.splitext(filename)[1].lower() == '.jpeg' or os.path.splitext(filename)[1].lower() == '.gif'}

然后把more code部分放进一个函数里,针对图片文件调用这个函数。不过,我在想,能不能在字典推导中让if条件变得灵活一些,这样我就可以为音乐文件和图片文件分别传入不同的if条件?

2 个回答

0

这个:

def a_func(extension):
    # some code
    for root, dirs, files in os.walk(rootDir, topdown='true'):
        source_files = {filename:root for filename in files if os.path.splitext(filename)[1].lower() == extension}
        # more code
        # ...
        # ...

符合你的需求吗?

4

我觉得你应该用fnmatch.fnmatch这个函数,或者甚至可以用fnmatch.filter()

from fnmatch import filter

for root, dirs, files in os.walk(rootDir):
    source_files = {filename: root for filename in filter(files, '*.jpg')}

不过,如果你需要匹配多个文件扩展名,使用str.endswith()会简单很多:

for root, dirs, files in os.walk(rootDir):
    source_files = {filename: root for filename in files if filename.endswith(('.jpg', '.png', '.gif'))}

.endswith(),你可以使用任何字符串或者扩展名的元组:

mp3s = '.mp3'
images = ('.jpg', '.png', '.gif')

然后使用:

extensions = images

for root, dirs, files in os.walk(rootDir):
    source_files = {filename: root for filename in files if filename.endswith(extensions)}

我不太明白你为什么在这里使用字典推导式;在循环的每次迭代中,root都是固定的。你可以直接这样做:

for root, dirs, files in os.walk(rootDir):
    source_files = dict.fromkeys(filter(files, '*.jpg'), root)

或者使用

for root, dirs, files in os.walk(rootDir):
    source_files = dict.fromkeys([f for f in files if f.endswith(extensions)], root)

如果你想创建一个包含所有文件的字典,且这些文件在一个嵌套的目录结构中,你需要把字典推导式放到外面,并把os.walk()的调用整合到字典推导式里面:

source_files = {filename: root 
    for root, dirs, files in os.walk(rootDir)
    for filename in files if f.endswith(extensions)}

我把所有的topdown='true'这一行都去掉了;默认情况下是topdown=True(注意:Python中的布尔值是TrueFalse,而不是字符串。之所以能工作,是因为'true'作为字符串是“真”的,在布尔上下文中被认为是True,因为它是非空的)。

撰写回答