如何按父路径对路径列表进行分组?

dea*_*n89 2 python path

我有一个路径列表,我希望它们根据它们来自的文件夹名称动态地分成它们应该属于的列表。前两个来自“tent1”文件夹,我希望它们一起放在一个列表中,依此类推。我不想对这些文件夹的名称进行硬编码,然后将路径附加到它们。例如:

paths = [
    '/var/lib/cons/states/tent1/tops-ok_2022_11_28', 
    '/var/lib/cons/states/tent1/tops-ok_2022_11_27',  
    '/var/lib/cons/states/tent2/tops-ok_2022_11_28', 
    '/var/lib/cons/states/tent2/tops-ok_2022_11_27', 
    '/var/lib/cons/states/tent3/tops-ok_2022_11_28', 
    '/var/lib/cons/states/tent3/tops-ok_2022_11_27', 
    '/var/lib/cons/states/tent4/tops-ok_2022_11_28', 
    '/var/lib/cons/states/tent4/tops-ok_2022_11_27',
    ]
Run Code Online (Sandbox Code Playgroud)

我希望它们是这样的:

[['/var/lib/cons/states/tent1/tops-ok_2022_11_28', 
  '/var/lib/cons/states/tent1/tops-ok_2022_11_27'], 
 ['/var/lib/cons/states/tent2/tops-ok_2022_11_28', 
  '/var/lib/cons/states/tent2/tops-ok_2022_11_27'],
 ['/var/lib/cons/states/tent3/tops-ok_2022_11_28', 
  '/var/lib/cons/states/tent3/tops-ok_2022_11_27'],
 ['/var/lib/cons/states/tent4/tops-ok_2022_11_28', 
  '/var/lib/cons/states/tent4/tops-ok_2022_11_27']]
Run Code Online (Sandbox Code Playgroud)

moz*_*way 6

如果您的输入按路径排序(即相同的路径是连续的),您可以使用itertools.groupby

from itertools import groupby
from os.path import dirname

out = [list(g) for _,g in groupby(paths, dirname)]
Run Code Online (Sandbox Code Playgroud)

如果路径未排序,您可以使用字典作为中间:

out = {}
for p in paths:
    (out.setdefault(dirname(p), [])
        .append(p)
    )
    
out = list(out.values())
Run Code Online (Sandbox Code Playgroud)

输出:

[['/var/lib/cons/states/tent1/tops-ok_2022_11_28',
  '/var/lib/cons/states/tent1/tops-ok_2022_11_27'],
 ['/var/lib/cons/states/tent2/tops-ok_2022_11_28',
  '/var/lib/cons/states/tent2/tops-ok_2022_11_27'],
 ['/var/lib/cons/states/tent3/tops-ok_2022_11_28',
  '/var/lib/cons/states/tent3/tops-ok_2022_11_27'],
 ['/var/lib/cons/states/tent4/tops-ok_2022_11_28',
  '/var/lib/cons/states/tent4/tops-ok_2022_11_27']]
Run Code Online (Sandbox Code Playgroud)

替代方案pathlib

from itertools import groupby
from pathlib import Path

out = [list(g) for _,g in groupby(paths, lambda x: Path(x).parent)]
Run Code Online (Sandbox Code Playgroud)