Reputation: 110113
I have the following to recursively list files in a directory:
import os
def listdir(dir):
items = [dir + '/' + item for item in os.listdir(dir)]
for item in items:
if not os.path.isdir(item):
print (item)
else:
listdir(item)
As a sort of academic exercise I wanted to see how the above could be converted into a loop without recursion. What would be an example of doing that? So far I had something along the lines of:
def listdir(dir):
while True:
items = os.listdir(dir)
for item in items:
if not is.path.isdir(item):
print (item)
else:
# ?
Upvotes: 2
Views: 1055
Reputation: 15309
You could use a FIFO queue (or equivalently, a deque):
def listdir(dir_initial):
q = queue.Queue()
q.put(dir_initial)
while not q.empty():
dir = q.get()
items = os.listdir(dir)
for item in items:
item = dir + '/' + item
if os.path.isdir(item):
q.put(item)
else:
print(item)
If we encounter a directory we add it to the queue for later processing. If the queue is empty we know that we are done.
Note that this implements breadth-first search as opposed to the recursive depth-first search, meaning you will get:
/a/
/b/
/a/1/
/a/2/
/b/9/
instead of
/a/
/a/1/
/a/2/
/b/
/b/9/
Upvotes: 6
Reputation: 110113
Here's an example using a stack:
def listdir(dir):
stack = [dir,]
while stack:
parent_dir = stack[-1]
items = [parent_dir + '/' + item for item in os.listdir(stack.pop())]
for item in items:
if not os.path.isdir(item):
print (item)
else:
stack.append(item)
Upvotes: 0
Reputation: 49373
Ok, after reconsidering, you can add the directiry to a list and process them
But your original code has some bugs and will not work
import os
def listdir(dir):
dirstoprocess = []
while True:
items = os.listdir(dir)
for item in items:
if os.path.isfile(os.path.join(dir, item)):
print (item)
else:
dirstoprocess.append(os.path.join(dir, item))
if len(dirstoprocess) > 0:
dir = dirstoprocess.pop(0)
else:
break
listdir("D:\mydi")
Upvotes: 0
Reputation: 538
You could build a 'stack' of directories to list, and every time you encounter a new directory, add it to the stack. You could then loop while the stack is not empty over all directories:
Upvotes: 1