列表推导式中不带结尾else的多个非嵌套if条件



(注意:在你急于寻找重复的if-else Q之前,请参阅下一节,了解为什么它们中的许多不适合我)

我想学习如何使用列表推导将两组代码块简化为一个:

filenameslist.extend(
[f[:-4] for f in filenames if (
f.endswith('.mp3') or
f.endswith('.wma') or
f.endswith('.aac') or
f.endswith('.ogg') or
f.endswith('.m4a')
)])
filenameslist.extend(
[f[:-5] for f in filenames if (
f.endswith('.opus')
)])

我试图在so中遵循这么多答案后使用以下代码实现它。然而,这些对我不起作用。请看看我现在有什么:

filenameslist.extend(
[(f[:-4] if (
f.endswith('.mp3') or
f.endswith('.wma') or
f.endswith('.aac') or
f.endswith('.ogg') or
f.endswith('.m4a')
) else (f[:-5] if f.endswith('.opus') else '')) for f in filenames])

最后不必要的else ''在我的列表中添加了一个我不需要的条目"。删除else或使用else pass会导致语法错误。

我可以从列表中手动删除''条目,但关键是要学习如何通过列表理解来完成这一步。我正在使用py3.8 .

在列表推导式的表达式中不可能声明"在这种情况下不生成项"之类的内容。(当扩展名不是允许的扩展名列表时)。

你必须重复你的测试:

filenames = ['test.mp3', 'something.opus', 'dontcare.wav']
l = [
f[:-5] if f.endswith('.opus') else f[:-4]
for f in filenames
if (
f.endswith('.mp3') or
f.endswith('.wma') or
f.endswith('.aac') or
f.endswith('.ogg') or
f.endswith('.m4a') or
f.endswith('.opus')
)
]
print(l)

注意,您可以使用os.path.splitext来简化您的工作:

import os
filenames = ['test.mp3', 'something.opus', 'dontcare.wav']
l = [
os.path.splitext(f)[0]
for f in filenames
if os.path.splitext(f)[1] in ['.mp3', '.wma', '.aac', '.ogg', '.m4a', '.opus']
]
print(l)

使用Path对象的内置属性,而不是自己解析名称:

from pathlib import Path
filenames = Path('/some/folder/').glob('*')
allowed_suffixes = ['.mp3', '.wma', '.aac', '.ogg', '.m4a', '.opus']
file_stems = set(f.stem for f in filenames if f.suffix in allowed_suffixes)
当然,你可以使用list而不是set。这看起来比复杂的列表推导式更简洁。如果您想保留文件的完整路径,请使用:
file_stems = set(f.parent / f.stem for f in filenames if f.suffix in allowed_suffixes)

str.endswith方法可以选择接受一个后缀元组,因此您可以简单地执行:

allowed_suffixes = '.mp3', '.wma', '.aac', '.ogg', '.m4a', '.opus'
filenameslist.extend(f[:f.rfind('.')] for f in filenames if f.endswith(allowed_suffixes))

您可以像下面这样使用rpartition:

filenameslist.extend([fn.rpartition('.')[0] for fn in filenames if fn[fn.rfind('.'):] in suffixes])

例子:

suffixes = ['.mp3', '.wma', '.aac', '.ogg', '.m4a', '.opus', '.wav']
filenames = ['test.mp3', 'something.opus', 'dontcare.wav', 'lara']
[fn.rpartition('.')[0] for fn in filenames if fn[fn.rfind('.'):] in suffixes]

输出:

['test', 'something', 'dontcare']

最新更新