0

I want to iterate over a directory and sort the files based on extension into separate lists. I want to use match case to do this rather than many separate else-ifs. Something along the lines of the following:

for file in os.listdir(dirpath):
    filename = os.fsdecode(file)
    match filename.endswith():
        case endswith('.jpg')|endswith('.jpeg'): #How can I check if the 'filename' string ends with these two?
            doSomething(filename)
        case endswith('.mp4'): #Or this?
            somethingElse(filename)
        case _: #Or if it is anything else?
            doDefault(filename)

How can I check if the filename.endswith('.jpg') possibility from within the match case statement? Is there a way to "pass" the strings as cases into the function in the match statement? Am I misusing match case, would it be better to stick with else-ifs in this scenario?

Mave
  • 81
  • 1
  • 1
  • 9

1 Answers1

5

If you're specifically interested in file extensions, you could use os.path.splitext to separate out the file extension, and then run your match. Something like

for file in os.listdir(dirpath):
    filename = os.fsdecode(file)
    _, extension = os.path.splitext(filename)
    match extension:
        case '.jpg' | 'jpeg':
            doSomething(filename)
        case '.mp4':
            somethingElse(filename)
        case _:
            doDefault(filename)
M.O.
  • 1,712
  • 1
  • 6
  • 18
  • great solution, but at this point I am also wondering if the behavior I described in the question is in anyway possible with match case syntax (using the cases as arguments for a function inside the match) – Mave Jul 17 '22 at 20:04
  • And for future readers it is maybe important to highlight that this match case syntax is **available since 3.10** (even though there is a tag). Here you can find some more information on this structural pattern matching [PEP 634](https://peps.python.org/pep-0634/) and a tutorial [PEP 636](https://peps.python.org/pep-0636/). – MisterNox Jul 17 '22 at 20:10
  • 2
    @Mave No, but also yes. There is no syntax for using an arbitrary function in pattern matching in PEP 634. **But**, as pointed out in [this answer](https://stackoverflow.com/a/72201246/11612918) the `match` statement uses the `==` operator, i.e. the `__eq__` method, which we can overload in Python. We could implement a class `StrEndMatcher` taking one string as input, whose `__eq__` method checks if that string ends with the other. Then you could use that as `match StrEndMatcher(filename)`, and keep everything else the same. – M.O. Jul 17 '22 at 20:39
  • Now, is that actually a good idea, or is it a bit too magical? I'll leave that up to your judgement. Let me know if you want a full example. – M.O. Jul 17 '22 at 20:42
  • @M.O. perfect, thanks for the info. I understand the overloading, but yeah you're right not very practical in this case. Just wanted to know if this arbitrary function behavior as you've described it was possible. Thanks for making it very clear! – Mave Jul 18 '22 at 02:27