Reputation: 5686
I'm looking for a pythonic way to move up n
directories from a given directory.
Let's say we have the example path /data/python_env/lib/python3.6/site-packages/matplotlib/mpl-data
. If we were to move up n=2
directories we should end up at /data/python_env/lib/python3.6/site-packages
.
The following works to move up n
directories:
up_n = lambda path, n: '/'.join(path.split('/')[:-n])
However, it's not very readable and fails for paths on windows machines. In essence, it doesn't feel a very pythonic solution.
Is there a better, more pythonic solution, maybe using the os
module?
Upvotes: 10
Views: 6603
Reputation: 123541
For Python 3.4+, pathlib
is probably the best choice.
That said, here's something that will also work in older versions (including Python 2.x):
import os
def up_n(path, n):
components = os.path.normpath(path).split(os.sep)
return os.sep.join(components[:-n])
if __name__ == '__main__':
path = '/data/python_env/lib/python3.6/site-packages/matplotlib/mpl-data'
result = up_n(path, 2)
print(result) # -> \data\python_env\lib\python3.6\site-packages
Upvotes: 2
Reputation: 2950
One solution to this could take advantage of the shorthand that ..
is the parent directory. So, using pathlib
you could write
from pathlib import Path
up_n = lambda orig, n: Path(orig).joinpath('/'.join(['..']*n))
Upvotes: 2
Reputation: 7241
You can use python os.path
module for this:
>>> p = '/data/python_env/lib/python3.6/site-packages/matplotlib/mpl-data'
>>> os.path.normpath(os.path.join(p, "..", ".."))
'/data/python_env/lib/python3.6/site-packages'
Or generically for n
,
os.path.normpath(os.path.join(*([p]+[".."]*n)))
This way, you don't care it is Windows \
or UNIX /
to be used. Python should handle this well. And, you got a one-liner.
Upvotes: 4
Reputation: 24289
You can use the pathlib module of the standard library:
from pathlib import Path
path = Path('/data/python_env/lib/python3.6/site-packages/matplotlib/mpl-data')
levels_up = 2
print(path.parents[levels_up-1])
# /data/python_env/lib/python3.6/site-packages
Upvotes: 20
Reputation: 140287
how about iterating with os.path.dirname
:
import os
s = "/data/python_env/lib/python3.6/site-packages/matplotlib/mpl-data"
for _ in range(2):
s = os.path.dirname(s)
print(s)
prints:
/data/python_env/lib/python3.6/site-packages
Upvotes: 10