2013-10-10 93 views
2

以下是我遇到的任務:比較2列表的內容

給定2個列表的列表,將它們過濾爲只有沒有任何共同點的項目。例如,如果內部列表相同,則將其過濾掉。如果內部列表至少有一個共同的項目,也將其過濾掉。

注意:只有一層嵌套。內部列表僅包含字符串。我有一個可行的解決方案,但它非常麻煩。尋找反饋改進:

首先,我在這兩個列表中篩選出準確匹配:

l3 = filter(lambda x: x not in l2, l1) 
l4 = filter(lambda x: x not in l1, l2) 

我最終沒有完全相同的項目列表2名列表。現在我想遍歷內部列表,並擺脫與其他內部列表共享項目的任何內容。

我做:

for i in l3: 
     for j in i: 
      for k in l4: 
       if j in k: 
        print j, k 
        removel3.append(tuple(i)) 
        removel4.append(tuple(k)) 
    for i in l4: 
     for j in i: 
      for k in l3: 
       if j in k: 
        removel3.append(tuple(k)) 
        removel4.append(tuple(i)) 
    for i in list(set(removel3)): 
     l3.remove(list(i)) 
    for i in list(set(removel4)): 
     l4.remove(list(i)) 

(建築東西單獨列出,因爲直接在迭代循環去除弄亂列表索引和跳躍項目從列表中刪除,必須有這樣做的更好的方法。 ,但我不知道。)

但是是的。它完成了工作,但是從元組到更多元組設置爲列表......聽起來非常和諧。 :)很高興看到任何反饋!

編輯:

樣品輸入:

l1 = [['A', 'B', 'C'], ['D', 'E'], ['F', 'G', 'H']] 
l2 = [['A', 'B', 'C'], ['D', 'I'], ['K', 'L', 'M']] 

所有上述轉換後,最終有:

>>> l3 
[['F', 'G', 'H']] 
>>> l4 
[['K', 'L', 'M']] 
+0

你能不能給一個樣本輸入和預期的輸出? – Claudiu

+0

向我們展示一些數據:樣本輸入和所需輸出。 – FMc

+1

@FMc:偉大的思想家一樣想 – Claudiu

回答

2

我覺得像這樣的過濾器是你想要什麼

filter(lambda sublist:not any(set(sublist).intersection(x) for x in list2),list1) 
+0

這隻返回第一個列表。也許你打算這樣做兩次? –

+0

是的,必須有一個與l2,l1,另一個與l1,l2。但它確實完成了工作。我沒有太多的使用.intersection()的經驗,需要研究一下。非常感謝! –

+0

作爲一個列表理解,這將更加pythonic和更有效率:'[listlist中的子列表如果不是任何(set(sublist).intersection(x)for list2]' – Claudiu

4

我不知道我理解你,但我我會給它一個鏡頭。

# first, get all elements from each list as a flat set. 
import itertools 
set1 = set(itertools.chain.from_iterable(list1)) 
set2 = set(itertools.chain.from_iterable(list2)) 

#Now, figure out which elements they have in common 
common_elements = set1 & set2 

#Now eliminate inner lists which have elements in the common set 
new_list1 = [lst for lst in list1 if not any(x in common_elements for x in lst)] 
new_list2 = [lst for lst in list2 if not any(x in common_elements for x in lst)] 

請注意,我可以這樣做,因爲子列表可以保持可哈希對象。

+0

如果沒有設置(lst).intersection(common_elements)''什麼?但是可能是比我的解決方案更有效率......但我認爲他們都工作:) –

+0

@JoranBeasley - '如果不是common_elements.intersection(lst)'會更有效率,我想使用它。使用'any'可以實現短路,因此在算法上會更好一些。當橡膠遇到道路時,我們需要用真實數據進行實際測試,以確定哪個實際上更快 - 「set.intersection」的實現可能擊敗了「any」的短路優勢。 – mgilson

+0

這也適用,但喬蘭的答案似乎更好,至少在審美上:)謝謝! –