Python Forum
scandir() recursively and return path + filename - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: scandir() recursively and return path + filename (/thread-10014.html)



scandir() recursively and return path + filename - malonn - May-09-2018

I have this code:
import os

def scanRecurse(baseDir):
    for entry in os.scandir(baseDir):
        if entry.is_file():
            yield entry.name
        else:
            yield from scanRecurse(entry.path)

for i in scanRecurse('D:\\App Back-Ups'):
    print(i)
it returns all files within the directory and subdirectories. How can I modify it to return the files with their full paths?


RE: scandir() recursively and return path + filename - thepythotutor - May-09-2018

Hello malonn, in that code you have some issues to work with, you can append de base directory to the entry name using the os.joinpath function

for Python 2 you have the scandir function in another module, like this

import os
import scandir
def scanRecurse(baseDir):
    for entry in scandir.scandir(baseDir):
        if entry.is_file():
            yield os.path.join(baseDir, entry.name)
        else:
            yield scanRecurse(entry.path)
 
for i in scanRecurse('D:\\App Back-Ups'):
    print(i)
but in python 3, scandir belongs to the os module

import os
def scanRecurse(baseDir):
    for entry in os.scandir(baseDir):
        if entry.is_file():
            yield os.path.join(baseDir, entry.name)
        else:
            yield scanRecurse(entry.path)
 
for i in scanRecurse('D:\\App Back-Ups'):
    print(i)
Remember to fix a bug in one of the yield statements

- The Python Tutor


RE: scandir() recursively and return path + filename - snippsat - May-09-2018

(May-09-2018, 01:12 AM)malonn Wrote: it returns all files within the directory and subdirectories. How can I modify it to return the files with their full paths?
It's easier to use os.walk(),which is recursive bye default.
Then just join root and files for full paths.
import os

for root,dirs,files in os.walk('D:\\App Back-Ups'):
    for file in files:
        print(os.path.join(root, file))



RE: scandir() recursively and return path + filename - malonn - May-09-2018

Thanks @thepythotutor and @snippsat. I hadn't even looked at "walk()" because the docs say how much more efficient scandir() is. I think I'll stick with good ol' scandir() for now.
Also, @thepythotutor, the line...

yield from scanRecurse(entry.path)
...is correct. I believe you said it was bugged (if that is what you meant)?


RE: scandir() recursively and return path + filename - snippsat - May-09-2018

(May-09-2018, 01:31 PM)malonn Wrote: @snippsat. I hadn't even looked at "walk()" because the docs say how much more efficient scandir() is.
os.walk() also use scandir PEP 471.
Quote:As part of this proposal, os.walk() will also be modified to use scandir() rather than listdir() and os.path.isdir().
This will increase the speed of os.walk() very significantly (as mentioned above, by 2-20 times, depending on the system).



RE: scandir() recursively and return path + filename - malonn - May-09-2018

Ah. Cool. I did not read that particular tidbit. Knowing that, I will switch; walk() uses fewer lines of code. Thanks for clearing that up for me, @snippsat.


RE: scandir() recursively and return path + filename - wavic - May-09-2018

os.walk is powerful. You will enjoy it