[Tutor] Pythonic? Building a full path from a "visual" file tree
stv
stvsmth at gmail.com
Tue Mar 21 18:42:25 CET 2006
Hey all,
I would like to expand the "visual" representation of a tree
hierarchy, given below, where child-ness is defined by indentation,
and folder-ness is highlighted with a trailing '/'
Input (test.txt):
dir1/
file1
file2
1-1/
file3
file4
dir2/
file5
The desired output is a fully qualified path for each input line:
dir1/
dir1/file1
dir1/file2
dir1/1-1/
dir1/1-1/file3
dir1/1-1/file4
dir2/
dir2/file5
I considered several brute-force solutions, but I persevered and came
to, what I think, is a more Pythonic solution. What do you think?
import string
def expand_tree(filetree):
indent = '\t'
stack = []
for f in filetree:
indents = f.count(indent)
while len(stack) > indents: stack.pop()
stack.append(f.strip())
yield string.join(stack,'')
if not f.endswith('/'): stack.pop()
lines = [line.rstrip() for line in file('test.txt')]
for i in expand_tree(lines): print i
Those familiar with subversion (particularly, svnlook tree
/path/to/repos) may recognize the problem space and the sample input
(except that I simplified things a bit here, using a tab to indicate
level-of-hierarchy instead of a single space, which could appear in
the filename). The real-world solution will use a regex to find run
of spaces at the start of element 'f'. It will also get input from
stdin instead of a file.
Questions:
Is the list comprehension the right idiom for getting a file into a
list, without the EOL chars? I'm hard-pressed to see how it could be
more concise, but this is Python :) and the rtrim() feels a little
off.
Is string.join() preferred to ''.join? Does importing all of string
outweigh the readability of string.join()?
Any subversion geeks know of way to eliminate this code with a native
svn command?
Did other folks choke on generators for as long as I did? I'm not
going to admit, publicly, how long that was :) But I found this little
test illustrative:
def gen():
yield 1
yield 2
yield 3
g = gen()
g.next()
>>> 1
g.next()
>>> 2
g.next()
>>> 3
g.next()
>>> [stack trace]
Beyond simple, but the obviousness of it is hidden in many of the
examples I saw.
More information about the Tutor
mailing list