2012-10-09 13 views
1

我有一組來自兩個不同目錄的文件名。重新實現__eq__與python中的symmetric_difference進行比較

currList=set(['pathA/file1', 'pathA/file2', 'pathB/file3', etc.]) 

我的代碼正在處理的文件,需要通過比較其在以前的迭代內容改變currList ,說processLst。 爲此,我計算對稱差:

toProcess=set(currList).symmetric_difference(set(processList)) 

其實,我需要的symmetric_difference上的完整文件名(pathA /文件1)基本名(文件1 ......)不 操作。

我想我需要重新實現__eq__運算符,但我不知道如何在Python中做到這一點。

  1. 是重新實現__eq__正確的做法? 或
  2. 還有另一種更好的/等價的方法嗎?

回答

1

你可以用發生器表達式的魔法做到這一點。

def basename(x): 
    return x.split("/")[-1] 

result = set(x for x in set(currList).union(set(processList)) if (basename(x) in [basename(y) for y in currList]) != (basename(x) in [basename(y) for y in processList])) 

應該這樣做。它爲您提供了出現在一個列表或另一個列表中的所有元素X,並且其名稱在兩個列表中的出現並不相同。

編輯: 與運行此:

currList=set(['pathA/file1', 'pathA/file2', 'pathB/file3']) 
processList=set(['pathA/file1', 'pathA/file9', 'pathA/file3']) 

回報:

set(['pathA/file2', 'pathA/file9']) 

這似乎是正確的。

+1

確實非常pythonic。謝謝你的幫助! –

+0

你不需要'union'參數中的顯式'set'。 –

2

這是一個令牌(可能構造不佳)itertools版本,如果速度變得令人擔憂,應該運行得更快一點(儘管贊同@ Zarkonnen的單線程非常的甜蜜,所以+1 :))。

from itertools import ifilter 

currList = set(['pathA/file1', 'pathA/file2', 'pathB/file3']) 
processList=set(['pathA/file1', 'pathA/file9', 'pathA/file3']) 

# This can also be a lambda inside the map functions - the speed stays the same 
def FileName(f): 
    return f.split('/')[-1] 

# diff will be a set of filenames with no path that will be checked during 
# the ifilter process 
curr = map(FileName, list(currList)) 
process = map(FileName, list(processList)) 
diff = set(curr).symmetric_difference(set(process)) 

# This filters out any elements from the symmetric difference of the two sets 
# where the filename is not in the diff set 
results = set(ifilter(lambda x: x.split('/')[-1] in diff, 
       currList.symmetric_difference(processList))) 
+0

感謝您的回答。實際上,在Zarkonnen帶着他的單線發球之前,我正在尋找這樣的東西。這裏的優點是能夠將其移植到另一種語言。 –

+0

@BrunovonParis沒問題,我同意Zarkonnen的答案更容易移植到其他語言。祝你好運! – RocketDonkey

+0

嗡嗡聲,嗯,我認爲你的可移植性更強(我認爲它很容易翻譯成C++)。不管怎樣,謝謝! –

相關問題