os.path.walk not pruning descent tree (and I'm not happy with that behavior?)
Gabriel Genellina
gagsl-py2 at yahoo.com.ar
Mon May 28 01:36:08 EDT 2007
En Sun, 27 May 2007 22:39:32 -0300, Joe Ardent <ardent at gmail.com> escribió:
> Good day, everybody! From what I can tell from the archives, this is
> everyone's favorite method from the standard lib, and everyone loves
> answering questions about it. Right? :)
Well, in fact, the preferred (and easier) way is to use os.walk - but
os.path.walk is fine too.
> Anyway, my question regards the way that the visit callback modifies
> the names list. Basically, my simple example is:
>
> ##############################
> def listUndottedDirs( d ):
> dots = re.compile( '\.' )
>
> def visit( arg, dirname, names ):
> for f in names:
> if dots.match( f ):
> i = names.index( f )
> del names[i]
> else:
> print "%s: %s" % ( dirname, f )
>
> os.path.walk( d, visit, None )
> ###############################
There is nothing wrong with os.walk - you are iterating over the names
list *and* removing elements from it at the same time, and that's not
good... Some ways to avoid it:
- iterate over a copy (the [:] is important):
for fname in names[:]:
if fname[:1]=='.':
names.remove(fname)
- iterate backwards:
for i in range(len(names)-1, -1, -1):
fname = names[i]
if fname[:1]=='.':
names.remove(fname)
- collect first and remove later:
to_be_deleted = [fname for fname in names if fname[:1]=='.']
for fname in to_be_deleted:
names.remove[fname]
- filter and reassign in place (the [:] is important):
names[:] = [fname for fname in names if fname[:1]!='.']
(Notice that I haven't used a regular expression, and the remove method)
--
Gabriel Genellina
More information about the Python-list
mailing list