在Python中显示所有父文件夹

在Python中显示所有父文件夹,python,tokenize,Python,Tokenize,这属于为了回答问题而提问的范畴(尽管如果答案比我的好,我会接受) 如何打印给定子文件夹的所有父文件夹的绝对路径。鉴于以下情况 '/home/marx/Documents/papers/communism' 返回 [ '/', '/home', '/home/marx', '/home/marx/Documents', '/home/marx/Documents/papers', '/home/marx/Documents/papers/communism' ] 注意代

这属于为了回答问题而提问的范畴(尽管如果答案比我的好,我会接受)

如何打印给定子文件夹的所有父文件夹的绝对路径。鉴于以下情况

'/home/marx/Documents/papers/communism'
返回

[
  '/',
  '/home',
  '/home/marx',
  '/home/marx/Documents',
  '/home/marx/Documents/papers',
  '/home/marx/Documents/papers/communism'
]

注意代码不必检查文件是否存在,但如果存在尾随正斜杠、周围空格或两个并排正斜杠,我不希望出现虚假输出

此最小块运行良好,但如果存在多个并排正斜杠,则会失败

#!/usr/bin/env python

import os

def getParents ( path ):    
   parents = [ path ]
   while path != '/':
      path = os.path.dirname ( path )
      parents.append ( path )
   parents.reverse()
   return parents 

if __name__ == '__main__':
   print getParents ( '/home/marx/Documents/papers/communism' )

这个最小的块工作得很好,但如果有多个并排的正向斜杠,则会失败

#!/usr/bin/env python

import os

def getParents ( path ):    
   parents = [ path ]
   while path != '/':
      path = os.path.dirname ( path )
      parents.append ( path )
   parents.reverse()
   return parents 

if __name__ == '__main__':
   print getParents ( '/home/marx/Documents/papers/communism' )

应该处理好一切

import os

def parents(x, sep = os.path.sep):
    x = os.path.normpath(x)
    if x == sep: # bail out if only leading '/'s
        return [x, ]
    elements = x.split(sep)
    res = list(sep.join(elements[:i]) for i in range(1, len(elements)+1))
    res[0] = sep # fix leading /
    return res



>>> x = '/home/marx/Documents///papers/communism/'
>>> parents(x) 
['/',
 '/home',
 '/home/marx',
 '/home/marx/Documents',
 '/home/marx/Documents/papers',
 '/home/marx/Documents/papers/communism']
编辑:正确处理“父项('///')”


编辑:通过添加可选参数“sep”简化代码,并使用normpath()(如另一个答案中所述)

应该可以处理大部分事情

import os

def parents(x, sep = os.path.sep):
    x = os.path.normpath(x)
    if x == sep: # bail out if only leading '/'s
        return [x, ]
    elements = x.split(sep)
    res = list(sep.join(elements[:i]) for i in range(1, len(elements)+1))
    res[0] = sep # fix leading /
    return res



>>> x = '/home/marx/Documents///papers/communism/'
>>> parents(x) 
['/',
 '/home',
 '/home/marx',
 '/home/marx/Documents',
 '/home/marx/Documents/papers',
 '/home/marx/Documents/papers/communism']
编辑:正确处理“父项('///')”


编辑:通过添加可选参数“sep”简化代码,并使用normpath()(如另一个答案中所述)

使用模块
os.path中的函数。path
-一方面它与平台无关,即相同的代码适用于Windows路径(在Windows安装上运行时)

使用
os.path.normpath()
可以优雅地处理重复和尾随路径分隔符以及包含“.”的路径。使用此选项而不是
os.path.abspath()
,因为从非绝对路径上的不同目录运行时会得到不同的结果

import os.path

def get_parents(path):
    parents = []
    path = os.path.normpath(path)
    while path:
        parents.insert(0, path)
        if path == '/':
            path = ''
        else:
            path = os.path.dirname(path)

    return parents

>>> print get_parents('')
['.']
>>> print get_parents('/')
['/']
>>> print get_parents('/////')
['/']
>>> print get_parents('/home/marx/Documents/papers/communism')
['/', '/home', '/home/marx', '/home/marx/Documents', '/home/marx/Documents/papers', '/home/marx/Documents/papers/communism']
>>> print get_parents('/home/marx/Documents/papers/communism/')
['/', '/home', '/home/marx', '/home/marx/Documents', '/home/marx/Documents/papers', '/home/marx/Documents/papers/communism']
>>> print get_parents('////home/marx////Documents/papers/communism/////')
['/', '/home', '/home/marx', '/home/marx/Documents', '/home/marx/Documents/papers', '/home/marx/Documents/papers/communism']
>>> print get_parents('home/marx////Documents/papers/communism/////')
['home', 'home/marx', 'home/marx/Documents', 'home/marx/Documents/papers', 'home/marx/Documents/papers/communism']
>>> print get_parents('/home/marx////Documents/papers/communism/////../Das Kapital/')
['/', '/home', '/home/marx', '/home/marx/Documents', '/home/marx/Documents/papers', '/home/marx/Documents/papers/Das Kapital']
>>> print get_parents('/home/marx////Documents/papers/communism/////../Das Kapital/')
['/', '/home', '/home/marx', '/home/marx/Documents', '/home/marx/Documents/papers', '/home/marx/Documents/papers/Das Kapital']
>>> print get_parents('/home/marx////Documents/papers/communism/////../Das Kapital/../../../../../../')
['/']

使用module
os.path
中的函数-一方面它与平台无关,即相同的代码适用于Windows路径(在Windows安装上运行时)

使用
os.path.normpath()
可以优雅地处理重复和尾随路径分隔符以及包含“.”的路径。使用此选项而不是
os.path.abspath()
,因为从非绝对路径上的不同目录运行时会得到不同的结果

import os.path

def get_parents(path):
    parents = []
    path = os.path.normpath(path)
    while path:
        parents.insert(0, path)
        if path == '/':
            path = ''
        else:
            path = os.path.dirname(path)

    return parents

>>> print get_parents('')
['.']
>>> print get_parents('/')
['/']
>>> print get_parents('/////')
['/']
>>> print get_parents('/home/marx/Documents/papers/communism')
['/', '/home', '/home/marx', '/home/marx/Documents', '/home/marx/Documents/papers', '/home/marx/Documents/papers/communism']
>>> print get_parents('/home/marx/Documents/papers/communism/')
['/', '/home', '/home/marx', '/home/marx/Documents', '/home/marx/Documents/papers', '/home/marx/Documents/papers/communism']
>>> print get_parents('////home/marx////Documents/papers/communism/////')
['/', '/home', '/home/marx', '/home/marx/Documents', '/home/marx/Documents/papers', '/home/marx/Documents/papers/communism']
>>> print get_parents('home/marx////Documents/papers/communism/////')
['home', 'home/marx', 'home/marx/Documents', 'home/marx/Documents/papers', 'home/marx/Documents/papers/communism']
>>> print get_parents('/home/marx////Documents/papers/communism/////../Das Kapital/')
['/', '/home', '/home/marx', '/home/marx/Documents', '/home/marx/Documents/papers', '/home/marx/Documents/papers/Das Kapital']
>>> print get_parents('/home/marx////Documents/papers/communism/////../Das Kapital/')
['/', '/home', '/home/marx', '/home/marx/Documents', '/home/marx/Documents/papers', '/home/marx/Documents/papers/Das Kapital']
>>> print get_parents('/home/marx////Documents/papers/communism/////../Das Kapital/../../../../../../')
['/']

@我不需要它吗?我记得有一段时间它引起了问题ack@EliBendersky我不需要它吗?我记得它导致了问题a,而b看起来比我的版本干净得多。我明天试试看。如果成功的话,我会接受这一点,这不是惊天动地的,但是对于父母('//')来说失败了。看起来比我的版本干净多了。我明天试试看。如果成功的话,我会接受这一点,这不是惊天动地的,但对父母('//')来说是失败的。这是所有答案中最好的。请注意,至少在mac上(家里没有linux),前导空格或尾随空格会导致奇怪的行为。@puk:奇怪的行为?在*nix空格中是有效的文件/目录名,例如,
“/a/b/c/d”
是有效的。它分解为
['''/a','/a/b','/a/b/c','/a/b/c/d']
@puk:您确实需要去除空格,但它们确实可以是有效的名称。如果你真的想把它们去掉,可以使用'/a/b/c/d'.strip()。这是最好的答案。请注意,至少在mac上(家里没有linux),前导空格或尾随空格会导致奇怪的行为。@puk:奇怪的行为?在*nix空格中是有效的文件/目录名,例如,
“/a/b/c/d”
是有效的。它分解为
['''/a','/a/b','/a/b/c','/a/b/c/d']
@puk:您确实需要去除空格,但它们确实可以是有效的名称。如果您真的想要删除它们,请使用'/a/b/c/d'.strip()。