2017-02-28 101 views
2

我有目錄的排序列表:刪除多個列表元素(子)

lst :=

./C01 
./C01/BOOST 
./C01/BOOST/src 
./C01/BOOST/src/template 
./C01/EmployeeAdmin 
./Spheres 
./db01/src/scottlib # added later 
./db03 
./db03/src 
./db03/src/examples 
./db03/src/exercises 
./txt2bmp 
./txt2bmp/data 
./txt2bmp/docs 
./txt2bmp/tests 
./txt2bmp/txt2bmp 
./txt2bmp_COPYED 
./txt2bmp_COPYED/data 
./txt2bmp_COPYED/docs 
./txt2bmp_COPYED/tests 
./txt2bmp_COPYED/txt2bmp 
./txt2bmp_cpp 
./txt2bmp_cpp/doc 

我試圖刪除所有子文件夾 - 如果存在的話 - ,但我無法做到這一點的一種不錯的pythonic方式。我與循環做到了,但是這是一個長期的,醜陋的和高深莫測的解決方案... 刪除後的名單應顯示是這樣的:

lst2 :=

./C01 
./Spheres 
./db01/src/scottlib 
./db03 
./txt2bmp 
./txt2bmp_COPYED 
./txt2bmp_cpp 

下一行是命令我試圖修改很多方面,但沒有成功...

[ i for i in lst if not i.startswith(lst[0])] 

也許你有一個想法,以優雅的方式解決這個問題?

+0

使用're'模塊(正則表達式)可以快速輕鬆地使用pa ttern like'\ ./ \ w + $' – ryugie

+0

你想要刪除子文件夾還是隻從列表中刪除它們? –

+0

對不起,我只想從列表中刪除它們。 – Chris

回答

0

我認爲這是卓有成效

lst2 = [a for a in lst if '/'.join(a.split('/')[:-1]) not in lst] 
for line in lst2: print line 

輸出:

./C01 
./Spheres 
./db03 
./txt2bmp 
./txt2bmp_COPYED 
./txt2bmp_cpp 
+0

您的解決方案適合我,我已經測試了幾個列表:)謝謝 – Chris

0

在你的情況,你可以做路徑分隔符的一個簡單的計數和使用,對於在列表理解過濾,保持爲1的數只物品:

lst2 = [i for i in lst if i.count('/')==1] 

考慮@讓 - FrançoisFabre的評論,你可以用os.sep代替/來增加片段的可移植性。

+0

這可能不是OP想要的。 –

+0

@ Ev.Kounis顯然,這是他們想要的。 –

+1

我會使用'os.sep'來使它變得可移植。而如果路徑是絕對的而不是'。/'呢?甚至相對沒有'。/'?作爲一般情況,這個問題真的很棘手。 –

0

還是先歸一化路徑(與os.path.relpath),然後分離第一組分,然後過濾以獨特的路徑(用set):

from os.path import relpath 
def strip_tail(path): 
    try: 
     return path[:path.index("/")] 
    except ValueError: 
     return path 

lst2 = list(set(strip_tail(relpath(dir)) for dir in lst))