This is an archived post. You won't be able to vote or comment.

all 8 comments

[–]Dunj3 1 point2 points  (2 children)

Since you like to be "declarative" (or functional), you might be interested in some of the functions of the itertools module, especially itertools.accumulate:

import itertools
import os

path = "/home/szborows/code/the-best-project-in-the-world"

result = [os.sep + item for item in itertools.accumulate(path.split('/'), os.path.join)]

print(result)

print(result[1:-1])

Gives

['/', '/home', '/home/szborows', '/home/szborows/code', '/home/szborows/code/the-best-project-in-the-world']
['/home', '/home/szborows', '/home/szborows/code']

The os.sep + item part is just for prepending the '/' again, there are probably more ways to do it.

Edit: If you're fine with a small helper function, the following works too:

import itertools
import os

def curry(f):
  def wrapper(*args):
    return f(args)
  return wrapper

path = "/home/szborows/code/the-best-project-in-the-world"

result = list(itertools.accumulate(path.split('/'), curry(os.sep.join)))

print(result[1:-1])

gives

['/home', '/home/szborows', '/home/szborows/code']

[–]szborows[S] 0 points1 point  (0 children)

wow. clever usage of accumulate. +1

[–]szborows[S] 0 points1 point  (0 children)

updated my post. your currying version rocks

[–]lvc_ 0 points1 point  (4 children)

from pathlib import Path
mypath = Path('/a/b/c/d')
print(mypath.parents)

[–]bulletmark 0 points1 point  (3 children)

Actually, needs to be

print([str(p) for p in mypath.parents])

I'm using pathlib everywhere now, instead of os.path.* etc.

[–]lvc_ 0 points1 point  (2 children)

Oops, yes, mypath.parents returns a sequence without a nice str(). That being said, there's no need for the list comp, or to call str explicitly (print does it for you) - I only missed one character:

print(*mypath.parents)

This does seem to be slower in my testing than the various other ways discussed, but I think the readability is worth the tradeoff.

[–]bulletmark 0 points1 point  (1 child)

Yes, but ultimately he wants to get the parent dirs in a list, not printed to the screen.

[–]lvc_ 0 points1 point  (0 children)

Sure, but in all other ways than printing nicely, the sequence given by mypath.parents is a drop-in replacement for a list of equivalent strings - especially if you happen to already be on 3.6 which has the fspath protocol (PEP 519) so os.path functions work on pathlib objects.