2012-11-21 55 views
0

使用找到共同的數據蟒蛇

def compare_lsts(list1,list2): 
    first_set = set(list1) 
    second_set=set(list2) 
    results =[x for x in list1 if x in list2] 
    print(results) 

和運行compare_lsts([1,2,3,4,5],[3,8,9,1,7])給出包含在這兩組數字,即[1,3]

然而,使列表1包含多於一個列表例如compare_lsts([[1,2,3,4,5],[5,8,2,9,12],[3,7,19,4,16]],[3,7,2,16,19])給出[],[],[]

我已經使用list1中的列表,然後是循環的結果。我顯然不知道我在做什麼。

基本上問題是:如何比較一個靜態列表中的項目和最多的列表?

+1

對於後一種情況,您的預期產出是多少?你只想找到* all *列表中的所有數字,或'list1'列表中任何*列表中的'list2'中的數字? – poke

回答

0

如果你是從第一個是在列表的所有元素後:

set(first).intersection(second, third) # fourth, fifth, etc... 
>>> set([1, 2, 3]).intersection([2, 3, 4], [3, 4, 5]) 
set([3]) 

如果你是從第一個是在其他列表中的任何元素後:

>>> set([1, 2, 3]) & set([4]).union([5]) 
set([2]) 

這樣,那麼一個簡單的FUNC:

def in_all(fst, *rst): 
    return set(fst).intersection(*rst) 

def in_any(fst, *rst): 
    it = iter(rst) 
    return set(fst) & set(next(it, [])).union(*it) 
+0

OP的列表'[5,8,2,9,12]'不能使用字符串序列呈現。更何況,你失去了實際的數據類型信息...... – poke

+0

@poke字符串與它有什麼關係?鍵入set('123')然後設置([1,2,3])更容易 - 它仍然是3個唯一對象用於演示目的(並且不確定數據類型信息的含義)... –

+0

'set (['2'])與set([2])不同,因爲'2'與'2'不同。儘管輸入起來可能更容易,但它更令人困惑,因爲初學者總是將字符串理解爲單個對象,而不是字符序列,因此您正混淆相關信息。 – poke

0

,但不知道這是最好的辦法:

所有的
def flat(l): 
    c_l = [] 
    for i in l: 
     if isinstance(i,list): 
      map(c_l.append,i) 
     else: 
      c_l.append(i) 
    return c_l 


def compare_lsts(a,b): 
    if all([True if isinstance(x,list) else False for x in a]): #if there is sublists in a 
     a = flat(a) #flats a 

    if all([True if isinstance(x,list) else False for x in b]): #if there is sublists in b 
     b = flat(b) #flats b 


    return list(set(a) & set(b)) #intersection between a and b 


print (compare_lsts([[1,2,3,4,5],[5,8,2,9,12],[3,7,19,4,16]],[3,7,2,16,19]) #[16, 3, 2, 19, 7]) 
+0

我從這個[],[],[]返回,很明顯,有些東西我做得不對,雖然我相信我已經完全按照上面的方式重新輸入了它,並使用Python Visualisor – user1478335

1

首先,你已經開始使用集,所以你一定要使用他們,因爲他們檢查時,圍堵更快。另外,還有一些已經是設置了幾個有用的內置功能,因此比較兩個列表,你可以相交集,以獲得那些在這兩個列表中的項目:

>>> set1 = set([1, 2, 3, 4, 5]) 
>>> set2 = set([3, 8, 9, 1, 7]) 
>>> set1 & set2 
{1, 3} 
>>> list(set1 & set2) # in case you need a list as the output 
[1, 3] 

同樣,你可以還發現兩個集合的聯盟獲得那些在任何組的項目:如果你想找到列表2是在任何列表1的子表中的所有項目

>>> set1 | set2 
{1, 2, 3, 4, 5, 7, 8, 9} 

所以,那麼你可以相交的所有帶有list2的子列表然後將所有這些結果聯合:

>>> sublists = [set([1, 2, 3, 4, 5]), set([5, 8, 2, 9, 12]), set([3, 7, 19, 4, 16])] 
>>> otherset = set([3, 7, 2, 16, 19]) 
>>> intersections = [sublist & otherset for sublist in sublists] 
>>> intersections 
[{2, 3}, {2}, {16, 3, 19, 7}] 
>>> union = set() 
>>> for intersection in intersections: 
     union = union | intersection 
>>> union 
{16, 19, 2, 3, 7} 

你也可以做一點點更好的使用functools.reduce

>>> import functools 
>>> functools.reduce(set.union, intersections) 
{16, 19, 2, 3, 7} 

同樣,如果你想真正相交的結果,你能做到這一點還有:

>>> functools.reduce(set.intersection, intersections) 
set() 

而且最後,你可以把這一切都打包成一個很好的功能:

def compareLists (mainList, *otherLists): 
    mainSet = set(mainList) 
    otherSets = [set(otherList) for otherList in otherLists] 

    intersections = [mainSet & otherSet for otherSet in otherSets] 
    return functools.reduce(set.union, intersections) # or replace with set.intersection 

而且使用這樣的:

>>> compareLists([1, 2, 3, 4, 5], [3, 8, 9, 1, 7]) 
{1, 3} 
>>> compareLists([3, 7, 2, 16, 19], [1, 2, 3, 4, 5], [5, 8, 2, 9, 12], [3, 7, 19, 4, 16]) 
{16, 19, 2, 3, 7} 

注意,我更換的功能參數的順序,因此主列表(在你的情況列表2)首先提到因爲這是一個別人都相比。

+0

哇!非常感謝你。我應該通過這個來正確理解語法 – user1478335

+0

當我使用上面所寫的多個集合的比較時,我得到'TypeError:不支持的操作數類型爲&:'list'和'set''我做了一些愚蠢的事情再次? – user1478335

+0

然後你沒有先做出一套; '&'的兩個操作數都需要設置。你可以通過'set(lst)'來轉換你的列表。 – poke