2011-04-25 20 views
1

是否可以在列表中傳遞「__ contains __」函數多於一個參數?我想檢查是否至少我在列表中的項目之一存在於不同的列表中。__contains__函數的多個參數

例如: [0,1,4,8,87,6,4,7,5, 'A', 'F', 'ER', 'FA', 'VZ']

我想檢查一下這些項目(8,5,'f')是否在列表中。

我該怎麼辦?

回答

2

您可以使用集:

list1 = [0,1,4,8,87,6,4,7,5,'a','f','er','fa','vz'] 
tuple1 = (8,5,'f') 

def my_contains(first, second): 
    return bool(set(first).intersection(second)) 

my_contains(list1, tuple1) # True 
my_contains(list1, [1]) # True 
my_contains(list1, (125,178,999)) # False 
+2

+1,很好的使用set。 _intersection()_可以直接進行第二次迭代。只需調用bool(someset)即可產生True/False。 'return bool(set(first).intersection(second))' – kevpie 2011-04-25 09:03:44

+1

需要注意的一個關鍵點是基於集合的方法僅適用於所有涉及的值都是可散列的情況。如果不能保證,那麼有必要採用迭代解決方案(可能使用「任何」內建函數)。 – ncoghlan 2011-04-25 16:50:56

7

AFAIK,__contains__只接受一個參數,不能更改。

但是你可以做以下,以獲得期望的結果:

>>> a = [0,1,4,8,87,6,4,7,5,'a','f','er','fa','vz'] 
>>> any(map(lambda x: x in a, (8,5,'f'))) 
True 

>>> from functools import partial 
>>> from operator import contains 
>>> f = partial(contains, a) 
>>> any(map(f, (2,3))) 
False 
+1

+1使用任何,也是不錯的展示部分。使用生成器代替map + lambda更加pythonic。 – kevpie 2011-04-25 08:58:50

+1

正如kevpie指出的那樣,第一個建議比「any(x in a for x in(8,5,'f'))''要乾淨得多。無論何時將lambda作爲第一個參數傳遞給map,這都暗示應該使用理解或生成器表達式。 – ncoghlan 2011-04-25 16:49:15

3

使用內置set類型。

>>> l = [0,1,4,8,87,6,4,7,5,'a','f','er','fa','vz'] 
>>> s = (8,5,'f') 
>>> bool(set(s) & set(l)) 
True 

設置方法也將迭代作爲參數,避免創建集合。

最簡潔:

2.6提供set.isdisjoint(其他)其可能被優化以只要一個共同的元件被發現返回。

>>> not set(l).isdisjoint(s) 
True 

如果你想循環:

>>> any((val in s) for val in l) 
True