Removing the first folder in a path
Solution 1:
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:
>>> import pathlib
>>> 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.
Solution 2:
A bit like another answer, taking advantage of os.path :
os.path.join(*(x.split(os.path.sep)[2:]))
... assuming your string starts with a separator.
Solution 3:
A simple approach
a = '/First/Second/Third/Fourth/Fifth'
"/".join(a.strip("/").split('/')[1:])
output:
Second/Third/Fourth/Fifth
In this above code i have split the string. then joined leaving 1st element
Using itertools.dropwhile
:
>>> a = '/First/Second/Third/Fourth/Fifth'
>>> "".join(list(itertools.dropwhile(str.isalnum, a.strip("/"))[1:])
'Second/Third/Fourth/Fifth'