2014-01-09 64 views
1

我有兩個元組列表:第一個(A)有我正在檢查的值集。第二(B)有,我想淘汰,如果他們出現在A.Python - 檢查元組列表中項目的組合

A = [(1, 2, 3), (6, 10, 8)] 
B = [(5, 7, 9), (10, 6)] 

正如你所看到的,檢查由事實複雜化值的組合是: 期B - 元組可能比A元組短 - B元組的長度可能不同 - B元組中的值可能以不同的順序出現,而不是A元組中的元素 - A元組的長度都相同,但長度可以「 t是預定的

我想出這樣做的最佳方式涉及一些冗餘:

bad_tuples = [tup for badtup in B for tup in A 
       if [baditem for baditem in badtup if baditem in tup] 
       and len([baditem for baditem in badtup if baditem in tup]) == len(badtup)] 
good_tuples = [tup for tup in A if tup not in bad_tuples] 

我認爲這可以完成工作,但我不喜歡這樣一個事實,即我必須在找到bad_tuples時重複相同的列表理解。我也覺得很難閱讀,所以很容易出錯。那麼任何人都可以想到一個更加優雅/高效的完成任務的方式嗎?

(如果它的事項,在我的應用程序也有可能是在一個許多(但< 100)元組和B中只有少數(< 10)元組)

+1

每個元組中的條目是唯一的嗎?將它們轉換爲集合可以簡化這一點,但顯然只有當條目在每個元組中都是唯一的時纔有效。 – richsilv

+0

單個項目可以出現在多個元組中,但每個組合(每個元組的值)在每個列表中都是唯一的。列表A是itertools.product()的結果,具有作爲參數提供的不確定數目的列表。但是有可能相同的項目可能出現在多個輸入列表中,在這種情況下,某些元組可能具有多個具有相同值的項目。 (這是一個足夠複雜的答案?) – monotasker

+1

謝謝,在這個基礎上是元組'(1,2)'不同於'(1,1,2)'?即'1'在'(1,1,2)'兩次的事實是否意味着即使'(1,2)'在B中你也不想從A中排除它? – richsilv

回答

4

如果一個元組內的條目確實獨特的,它應該是這麼簡單:

[x for x in A if set(x) not in [set(y) for y in B]] 

UPDATE

基礎上的評論,似乎排除應該是所有元組A中的元組B是當所有東西都被轉換成集時的子集。所以它是:

[x for x in A if not any([set(y).issubset(set(x)) for y in B])] 
+0

我剛剛在上面添加了一條評論,說明元組中可能存在重複值。但是這太簡單了,我可能會嘗試重構周圍的邏輯以使元組適合。 – monotasker

+0

傻我。我剛剛意識到,鑑於我在上述評論中的闡述,元組中的項是否是唯一的並不重要。 (即,我只查找任意次數的值的組合,所以set()應該可以正常工作。) – monotasker

+0

謝謝。太精彩了。我甚至不知道集合的issubset()方法。 (關閉閱讀文檔。) – monotasker

0

這應該工作。

for tup in B: 
    if(tup in A): 
     bad_tuples.append(tup) 
    else: 
     good_tuples.append(tup) 

假設元組的元素的順序是相關的。

+0

謝謝。雖然這是真正的伎倆。元素的順序是不相關的,我想過濾掉A元組中的元組,它們與B元組具有相同*組合*,即使存在其他值。 (請參閱上面評論中的說明。) – monotasker

+0

好的,我看到了問題。然後我必須再考慮一下。 – EarlGrey