I have a function that returns the full path of a specific parent that I look for by a constant name. I am currently using os.path
and strings for paths so right now this is done with regular-expressions.
What I want is for example for a constant parent = d
to be able to get:
/a/b/c/d/e --> /a/b/c/d
/a/b/c/d/e/f --> /a/b/c/d
/root/a/b/c/d/e --> /root/a/b/c/d
Note: as the example shows I don't want to rely on any fixed position from both sides.
I have tried 2 ways but both feels a bit clunky:
Use the parts
in order to find the correct parents
element:
>>> path = "/a/b/c/d/e/f"
>>> parts = Path(path).parts
>>> parent_index = len(parts) - 1 - parts.index('d') - 1
>>> Path(path).parents[parent_index]
PosixPath('/a/b/c/d')
Use the parts
and concatenate the relevant ones:
>>> path = "/root/a/b/c/d/e"
>>> parts = Path(path).parts
>>> Path(*parts[:parts.index('d')+1])
PosixPath('/root/a/b/c/d')
I would say that the second one seems reasonable, but still, my question is: Is there a more direct, pythonic way to achieve this? The repeated indexing and slicing of the parents
feels inefficient and quite confusing.
P.S. In case the part is not present in the path it is enough to raise an exception or any indicator (right now I wrap the code with index
above with a try/except
).
You can use a while
loop instead to keep searching backwards for a parent of the given name:
path = Path("/a/b/c/d/e/f")
while path.name != 'd':
path = path.parent
assert path.name, 'No parent found with the given name'
print(path)
This outputs:
/a/b/c/d