(Note: before you jump the gun to look for duplicate if-else Q's, please see the next section for why many of them did not suit mine)
I want to learn how to use list comprehension to simplify the two set of code block into one:
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')
)])
I have tried to achieve it using the following code after following so many answers here in SO. However, these doesn't work for me. Please have a look at what I have right now:
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])
The unnecessary else ''
at the end adds an entry '' to my list which I don't need. Removing the else or using else pass
results in syntax error.
I can delete the ''
entry manually from list, but the point is to learn how to do this one-step with list comprehension. I am using py 3.8.
CodePudding user response:
Use the Path
objects' built-in properties instead of parsing the names yourself:
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)
You can use a list instead of a set, of course. This looks cleaner than a convoluted list comprehension. If you want to retain the files' full paths, use:
file_stems = set(f.parent / f.stem for f in filenames if f.suffix in allowed_suffixes)
CodePudding user response:
There is no way in the expression of your list comprehension to state something like "do not produce an item in that case" (when the extension is not your list of allowed extensions).
You have to somehow repeat your test:
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)
Note that you can use os.path.splitext
to ease your work:
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)
CodePudding user response:
The str.endswith
method can optionally take a tuple of suffixes, so you can simply do:
allowed_suffixes = '.mp3', '.wma', '.aac', '.ogg', '.m4a', '.opus'
filenameslist.extend(f[:f.rfind('.')] for f in filenames if f.endswith(allowed_suffixes))
CodePudding user response:
You can use rpartition
like below:
filenameslist.extend([fn.rpartition('.')[0] for fn in filenames if fn[fn.find('.'):] in suffixes])
Example:
suffixes = ['.mp3', '.wma', '.aac', '.ogg', '.m4a', '.opus', '.wav']
filenames = ['test.mp3', 'something.opus', 'dontcare.wav', 'lara']
filenameslist.extend([fn.rpartition('.')[0] for fn in filenames if fn[fn.find('.'):] in suffixes])
Output:
['test', 'something', 'dontcare']