Do I Understand Os.Walk Right

Do I understand os.walk right?

os.walk returns a generator, that creates a tuple of values (current_path, directories in current_path, files in current_path).

Every time the generator is called it will follow each directory recursively until no further sub-directories are available from the initial directory that walk was called upon.

As such,

os.walk('C:\dir1\dir2\startdir').next()[0] # returns 'C:\dir1\dir2\startdir'
os.walk('C:\dir1\dir2\startdir').next()[1] # returns all the dirs in 'C:\dir1\dir2\startdir'
os.walk('C:\dir1\dir2\startdir').next()[2] # returns all the files in 'C:\dir1\dir2\startdir'

So

import os.path
....
for path, directories, files in os.walk('C:\dir1\dir2\startdir'):
if file in files:
print('found %s' % os.path.join(path, file))

or this

def search_file(directory = None, file = None):
assert os.path.isdir(directory)
for cur_path, directories, files in os.walk(directory):
if file in files:
return os.path.join(directory, cur_path, file)
return None

or if you want to look for file you can do this:

import os
def search_file(directory = None, file = None):
assert os.path.isdir(directory)
current_path, directories, files = os.walk(directory).next()
if file in files:
return os.path.join(directory, file)
elif directories == '':
return None
else:
for new_directory in directories:
result = search_file(directory = os.path.join(directory, new_directory), file = file)
if result:
return result
return None

os.walk without digging into directories below

Use the walklevel function.

import os

def walklevel(some_dir, level=1):
some_dir = some_dir.rstrip(os.path.sep)
assert os.path.isdir(some_dir)
num_sep = some_dir.count(os.path.sep)
for root, dirs, files in os.walk(some_dir):
yield root, dirs, files
num_sep_this = root.count(os.path.sep)
if num_sep + level <= num_sep_this:
del dirs[:]

It works just like os.walk, but you can pass it a level parameter that indicates how deep the recursion will go.

Python: Too many values to unpack (what does the os.walk function return)

You already know that list(os.walk(...))[0] == ('test_dir', [], ['somefile1', 'somefile2']), which is a tuple.

This code:

for a, b, c in thing:
...

...is the same as this:

for something in thing:
a, b, c = something
...

This part: a, b, c = something is called "iterable unpacking".

Note that the loop will attempt to iterate over each element of thing. In your case, it'll try to iterate over each of the three elements of your tuple, and on the first iteration something == 'test_dir', which is an iterable that contains 8 elements.

However, a, b, c = something expects it to have exactly three elements. So, you get an error saying that there were too many values to unpack (expected 3 but got 8).

How does the iteration of os.walk work in Python 3?

os.walk doesn't return a 3-tuple, it yields multiple 3-tuples. From the docs:

For each directory in the tree rooted at directory top (including top itself), it yields a 3-tuple (dirpath, dirnames, filenames).

For how yielding works, see What does the "yield" keyword do? (You can ignore the example code given by OP.) Technically os.walk returns a generator that yields the 3-tuples.

The outer for loop iterates over the 3-tuples. You're probably confused by the unpacking that happens in the same step. So to be clear,

for dirpath, dirnames, filenames in os.walk(top):

is effectively the same as

for branch in os.walk(top):
dirpath, dirnames, filenames = branch

os.walk not giving right path

I think the problem is that you're reusing the root variable while you're walking the directory and parsing XML at the same time. After you've parsed one XML file, the root variable became the root element of parse tree, but in next iteration of the loop, you are still using root variable as the directory name.

Can I force os.walk to visit directories in alphabetical order?

Yes. You sort dirs in the loop.

def main_work_subdirs(gl):
for root, dirs, files in os.walk(gl['pwd']):
dirs.sort()
if root == gl['pwd']:
for d2i in dirs:
print(d2i)


Related Topics



Leave a reply



Submit