1
\$\begingroup\$

I have written this code to build a list by looking inside directory within deep to the level it finds a audio file and then move to the next level or next folder.

Can there be a more efficient way since a user can have any number of files? Do you think it can be achieved more robustly in terms of performance?

path = '/Users/ceaser/Music'

import os
allSongs = []
for folder in os.walk(path):
    for item in folder[-1]:
        name, ext = os.path.splitext(item)
        if ext in ['.mp3', '.wma', '.wav', '.ogg']:
            allSongs.append(name)
\$\endgroup\$
  • \$\begingroup\$ os.listdir is faster then os.walk. \$\endgroup\$ – Ricky Wilson Aug 21 '15 at 18:16
1
\$\begingroup\$

The performance of this will largely depend on filesystem I/O, and the number of files and subdirectories in your target folder.

It won't make a difference in practice, but in theory it will be faster to check the extension against a set instead of a list, for example:

extensions = {'.mp3', '.wma', '.wav', '.ogg'}
for dirpath, dirnames, filenames in os.walk(path):
    for item in filenames:
        name, ext = os.path.splitext(item)
        if ext in extensions:
            allSongs.append(name)

Notice that I changed the for folder in os.walk(path) to the more intuitive for dirpath, dirnames, filenames in os.walk(path), which makes the inner loop more intuitive too, for item in filenames instead of the cryptic for item in folder[-1].

But most of all, I'm wondering if it's really os.walk you want to use. This function is useful for traversing a directory tree, down into arbitrary levels of subdirectories. I'm questioning your intention because you only keep filenames, not their paths. So for example a song The Four Horsemen.mp3 may exist in both /Users/ceaser/Music/Metallica and in /Users/ceaser/Music/Mix/Oldies-But-Goodies, and then you will have The Four Horsemen.mp3 in allSongs twice. Not caring about the intermediary directories suggests that perhaps there are no intermediary directories, all songs are simply directly under /Users/ceaser/Music. In that case, instead of os.walk, using os.listdir would be more appropriate and simpler too.

Lastly, there is an official coding style guide for Python, called PEP8, I recommend to give it a good read and follow it in the future.

\$\endgroup\$
  • \$\begingroup\$ i think using listdir we would need to go by recursive function approach which I was thinking will be adding extra overhead \$\endgroup\$ – Ciasto piekarz Aug 22 '15 at 6:12
  • \$\begingroup\$ I recommended listdir only in the case if you have a flat directory layout. If you have subdirectories then os.walk is simple and fine. It seems you misunderstood my post \$\endgroup\$ – janos Aug 22 '15 at 6:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.