Python:获取路径中所有父级的iterable的捷径

Python:获取路径中所有父级的iterable的捷径,python,iterable,Python,Iterable,使用基于路径的资源系统时,应用程序需要找到第一个基于路径管理给定资源的工作资源。我需要一种简洁的python方法来生成以下内容: 输入: /house/dogs/ralph/bone /house/dogs/ralph/bone /house/dogs/ralph /house/dogs /house 输出: /house/dogs/ralph/bone /house/dogs/ralph/bone /house/dogs/ralph /house/dogs /house 注意:可以使用

使用基于路径的资源系统时,应用程序需要找到第一个基于路径管理给定资源的工作资源。我需要一种简洁的python方法来生成以下内容:

输入:

/house/dogs/ralph/bone
/house/dogs/ralph/bone
/house/dogs/ralph
/house/dogs
/house
输出:

/house/dogs/ralph/bone
/house/dogs/ralph/bone
/house/dogs/ralph
/house/dogs
/house
注意:可以使用
os.path
或类似的内置程序,但这些不是文件系统资源。输出可以是任何可编辑的内容(列表、设置、生成器等)。

使用。s为与文件系统没有关系的类似路径的对象提供了一个抽象接口。特别是使用前斜杠(
/
)作为分隔符的类型:

>>> from pathlib import PurePosixPath
>>> p = PurePosixPath('/house/dogs/ralph/bone')
>>> str(p.parent)
/house/dogs/ralph
>>> str(p.parent.parent)
/house/dogs
您可以轻松地循环此操作:

p = PurePosixPath(...)
while p != p.root:
    # Do stuff to p
    p = p.parent
让它成为一台发电机将是一个相当完美的画龙点睛之作:

def receding_path(p):
    p = PurePosixPath(p)
    while p != p.root:
        yield str(p)
        p = p.parent

for item in receding_path('/house/dogs/ralph/bone'):
    # do stuff to each item
使用。s为与文件系统没有关系的类似路径的对象提供了一个抽象接口。特别是使用前斜杠(
/
)作为分隔符的类型:

>>> from pathlib import PurePosixPath
>>> p = PurePosixPath('/house/dogs/ralph/bone')
>>> str(p.parent)
/house/dogs/ralph
>>> str(p.parent.parent)
/house/dogs
您可以轻松地循环此操作:

p = PurePosixPath(...)
while p != p.root:
    # Do stuff to p
    p = p.parent
让它成为一台发电机将是一个相当完美的画龙点睛之作:

def receding_path(p):
    p = PurePosixPath(p)
    while p != p.root:
        yield str(p)
        p = p.parent

for item in receding_path('/house/dogs/ralph/bone'):
    # do stuff to each item

一种方法是在
“/”
上拆分字符串,并连续切片

in_string = "/house/dogs/ralph/bone"
s = in_string.split("/")
out_strings = list(filter(None, ("/".join(s[:i+1]) for i in range(len(s)))))
print(out_strings)
#['/house', '/house/dogs', '/house/dogs/ralph', '/house/dogs/ralph/bone']
过滤器(None,…)
用于删除空字符串

或者,如果您希望按照您在帖子中指定的顺序输出,请反转范围:

out_strings = list(filter(None, ("/".join(s[:i]) for i in range(len(s), 0, -1))))
print(out_strings)
#['/house/dogs/ralph/bone',
# '/house/dogs/ralph',
# '/house/dogs',
# '/house']

一种方法是在
“/”
上拆分字符串,并连续切片

in_string = "/house/dogs/ralph/bone"
s = in_string.split("/")
out_strings = list(filter(None, ("/".join(s[:i+1]) for i in range(len(s)))))
print(out_strings)
#['/house', '/house/dogs', '/house/dogs/ralph', '/house/dogs/ralph/bone']
过滤器(None,…)
用于删除空字符串

或者,如果您希望按照您在帖子中指定的顺序输出,请反转范围:

out_strings = list(filter(None, ("/".join(s[:i]) for i in range(len(s), 0, -1))))
print(out_strings)
#['/house/dogs/ralph/bone',
# '/house/dogs/ralph',
# '/house/dogs',
# '/house']

前两个答案的组合:

import pathlib
import os
def resources(path):
  parts = pathlib.Path(path).parts
  for n in range(len(parts), 1, -1):
    yield os.path.join(*parts[:n])

前两个答案的组合:

import pathlib
import os
def resources(path):
  parts = pathlib.Path(path).parts
  for n in range(len(parts), 1, -1):
    yield os.path.join(*parts[:n])


为什么你不能在
/
上拆分字符串并切片?我可以。我正在寻找最好的(蟒蛇式)方法。我的第一个想法是在递归函数中拆分/联接,
产生
结果,但肯定有更好的方法。我更新了我的答案,强调纯posix路径的非文件性质为什么你不能拆分
/
上的字符串并进行切片?我可以。我正在寻找最好的(蟒蛇式)方法。我的第一个想法是在递归函数中拆分/联接,
生成
ing结果,但必须有更好的方法。我更新了我的答案,以强调纯posix路径的非文件性质。问:你为什么要过滤而不只是引用
[:-1]
因为只有最后一个元素是空的?@Bobby分隔符可以出现在路径中字符串的开头或结尾。在
拆分之后
,这将导致空字符串。使用
过滤器
我不必找出要排除的索引,它会维护生成器(无法索引)。好奇:有什么原因让你过滤而不只是引用
[:-1]
,因为只有最后一个元素是空的吗?@Bobby分隔符可以出现在路径中字符串的开头或结尾。在
拆分之后
,这将导致空字符串。使用
过滤器
我不必找出要排除的索引,它会维护生成器(无法索引)。您可能希望使用
'/'.join
而不是
os.path.join
使其独立于操作系统。那么也许可以去掉第一个元素?我的印象是os.path.join是独立于操作系统的,使用“/”将使其依赖于操作系统(仅适用于基于Unix的系统)。os.path.join也会自动对顶级元素做正确的处理。@JeffreyFroman,我相信@MadPhysicast的意思是,如果您使用
os.path.join
,如果您不使用*nix系统,结果会有所不同。它的操作系统独立性将使您的解决方案不在Linux上运行。对,我认为@Bobby:
OS.path.join将使用该操作系统。该操作系统的路径分隔符。如果我们处理的字符串是文件系统路径,那么这些字符串可能会包含适用于该操作系统的分隔符。如果字符串不是我们将要运行的操作系统的文件系统路径,那么pathlib根本不起作用,我们必须对原始字符串和字符进行操作。我们同意os.path.join的工作原理——如果我们要使用pathlib,我们已经假设我们正在使用适合我们正在运行的操作系统的路径。@Bobby。恰恰相反。它将按需要在Linux上运行,但不能在Windows上运行。OP正在所有系统上查找正斜杠分隔的路径。您可能希望使用
'/'.join
而不是
os.path.join
使其独立于操作系统。那么也许可以去掉第一个元素?我的印象是os.path.join是独立于操作系统的,使用“/”将使其依赖于操作系统(仅适用于基于Unix的系统)。os.path.join也会自动对顶级元素做正确的处理。@JeffreyFroman,我相信@MadPhysicast的意思是,如果您使用
os.path.join
,如果您不使用*nix系统,结果会有所不同。它的操作系统独立性将使您的解决方案不在Linux上运行。对,我认为@Bobby:
OS.path.join将使用该操作系统。该操作系统的路径分隔符。如果我们处理的字符串是文件系统路径,那么这些字符串可能会包含适用于该操作系统的分隔符。如果字符串不是我们将要运行的操作系统的文件系统路径,那么pathlib根本不起作用,我们必须对原始字符串和字符进行操作。我们同意os.path.join的工作原理——如果我们要使用pathlib,我们已经假设我们正在使用适合我们正在运行的操作系统的路径。@Bobby。恰恰相反。它将按需要在Linux上运行,但不能在Windows上运行。OP正在所有系统上查找正斜杠分隔的路径。
pathlib
还提供了
path.parents
属性。来自文档的定义:不可变的se