meto meto - 4 months ago 21
Python Question

Removing the first folder in a path

I have a path which looks like

/First/Second/Third/Fourth/Fifth


and I would like to remove the
First
from it, thus obtaining

Second/Third/Fourth/Fifth


The only idea I could come up with is to use recursively
os.path.split
but this does not seem optimal. Is there a better solution?

Answer

There really is nothing in the os.path module to do this. Every so often, someone suggests creating a splitall function that returns a list (or iterator) of all of the components, but it never gained enough traction.

Partly this is because every time anyone ever suggested adding new functionality to os.path, it re-ignited the long-standing dissatisfaction with the general design of the library, leading to someone proposing a new, more OO-like, API for paths to deprecated the os, clunky API. In 3.4, that finally happened, with pathlib. And it's already got functionality that wasn't in os.path. So:

>>> p = pathlib.Path('/First/Second/Third/Fourth/Fifth')
>>> p.parts[2:]
('Third', 'Fourth', 'Fifth')
>>> pathlib.Path(*p.parts[2:])
PosixPath('Second/Third/Fourth/Fifth')

Or… are you sure you really want to remove the first component, rather than do this?

>>> p.relative_to(*p.parts[:2])
PosixPath('Second/Third/Fourth/Fifth')

If you need to do this in 2.6-2.7 or 3.2-3.3, there's a backport of pathlib.

Of course, you can use string manipulation, as long as you're careful to normalize the path and use os.path.sep, and to make sure you handle the fiddly details with non-absolute paths or with systems with drive letters, and…

Or you can just wrap up your recursive os.path.split. What exactly is "non-optimal" about it, once you wrap it up? It may be a bit slower, but we're talking nanoseconds here, many orders of magnitude faster than even calling stat on a file. It will have recursion-depth problems if you have a filesystem that's 1000 directories deep, but have you ever seen one? (If so, you can always turn it into a loop…) It takes a few minutes to wrap it up and write good unit tests, but that's something you just do once and never worry about again. So, honestly, if you don't want to use pathlib, that's what I'd do.

Comments