2010-01-22 90 views
5

我列出任意數量的列表中找到相同的物品,例如:的Python:在多個列表

[[1,2,3], [3,4,5], [5,6,7], [7,8,9]] 

現在我想包含存在於多個列表中的所有元素的列表:

[3,5,7] 

我該怎麼做?

謝謝!

回答

13

比較數字如你自己動手完成它:

seen = set() 
repeated = set() 
for l in list_of_lists: 
    for i in set(l): 
    if i in seen: 
     repeated.add(i) 
    else: 
     seen.add(i) 

順便說一句,這裏的一個襯墊(不計進口),一些人正在尋求(應該是比其他方法效率較低)

from itertools import * 
reduce(set.union, (starmap(set.intersection, combinations(map(set, ll), 2)))) 
+0

大集合的使用! – Khelben 2010-01-22 09:45:40

+7

請注意,因爲'l'還需要'設置',否則您會在[[1,1],[2,2]] – Khelben 2010-01-22 09:58:06

+0

+1中得到誤報,因爲@ Kbhelben認爲您應該可讀性爲 – tback 2010-01-22 09:58:09

-2

扁平化,排序,1迴路用同樣的方法之前和之後

+0

如果在出現兩次的數字。這將失敗同樣的名單。 – 2010-01-22 09:47:22

+0

如果你先拼合,你會得到一個「誤報」,如:[[1,1],[2,2]] – truppo 2010-01-22 09:48:54

1

您可以使用字典來獲得每個

from collections import defaultdict 

init_list = [[1,2,3], [3,4,5], [5,6,7], [7,8,9]] 
#defaultdict, every new key will have a int(0) as default value 
d = defaultdict(int) 
for values in init_list: 
    #Transform each list in a set to avoid false positives like [[1,1],[2,2]] 
    for v in set(values): 
    d[v] += 1 

#Get only the ones that are more than once 
final_list = [ value for value,number in d.items() if number > 1 ] 
+0

對'collections.defaultdict'看起來不錯。 – muhuk 2010-01-22 10:38:00

+0

@muhuk。是!你是絕對正確的!我更改了代碼。 Python的標準庫真的很大,並且有很多有用的東西... – Khelben 2010-01-22 10:57:41

0
l=[[1,2,3], [3,4,5], [5,6,7], [7,8,9]] 
d={} 
for x in l: 
    for y in x: 
     if not d.has_key(y): 
      d[y]=0 
     d[y]+=1 
[x for x,y in d.iteritems() if y>1] 
3

引用的次數:http://docs.python.org/library/stdtypes.html#set

#!/usr/bin/python 

ll = [[1,2,3], [3,4,5], [5,6,7], [7,8,9]] 
ls = [set(l) for l in ll] 

su = ls[0] #union 
ssd = ls[0] #symmetric_difference 
for s in ls[1:]: 
    su = su.union(s) 
    ssd = ssd.symmetric_difference(s) 

result = su.difference(ssd) 
print list(result) 

=>

[3, 5, 7] 

修改,並採用FP,

ll = [[1,2,3], [3,4,5], [5,6,7], [7,8,9]] 

u = reduce(set.union, map(set, ll)) 
sd = reduce(set.symmetric_difference, map(set, ll)) 
print u - sd 

=>

[3, 5, 7] 
+0

其實你的解決方案對於我的測試用例如lst_of_lst = [[65L,66L,81L,95L,96L,128L​​,171L,193L,218L ,304L,305L,338L,353L,355L,357L,412L], [86L,98L,154L,356L], [75L,154L], [38L,57L,65L,145L,175L, 420L,429L,439L], [75L,161L], [66L,109L,128L​​,137L,142L,154L,183L,184L,187L,203L,233L,285L,289L,343L] '[128L,65L,66L,154L,75L]',但是你的解決方案錯過了'154L' – LancelotHolmes 2017-03-10 08:49:00

1

試試這個:

data = [[1,2,3], [3,4,5], [5,6,7], [7,8,9], [1,2,3]] 

res = set() 

for i in data: 
    for j in data: 
     if i is not j: 
      res |= set(i) & set(j) 

print res 
5

乾淨的方式很可能是使用減少:

def findCommon(L): 
    def R(a, b, seen=set()): 
     a.update(b & seen) 
     seen.update(b) 
     return a 
    return reduce(R, map(set, L), set()) 

result = findCommon([[1,2,3], [3,4,5], [5,6,7], [7,8,9]]) 

結果是一組,但只是做list(result)如果你真的需要一個列表。

+0

+1的功能編程。 – 2010-01-22 10:02:31

+0

@Dyno'seen'變量在調用之間包含一個「隱藏的」可變狀態...函數式編程不應該依賴副作用(如果它們不明確,這是一個危險,我敢打賭,大多數人不會注意到看起來扮演的是「靜態」變量而不是常規參數) – fortran 2010-01-22 11:40:06

+0

@fortran:像R這樣的函數的典型用法是一次性的,因爲它們被放置在另一個函數內而不是在模塊級別。我會更新答案以使其更清楚。 – truppo 2010-01-22 11:50:09

1
>>> sets = [[1,2,3], [3,4,5], [5,6,7], [7,8,9]] 
>>> seen = set() 
>>> duplicates = set() 
>>> 
>>> for subset in map(set, sets) : 
...  duplicates |= (subset & seen) 
...  seen |= subset 
... 
>>> print(duplicates) 
set([3, 5, 7]) 
>>> 

我試圖用的map/reduce單行答案,但不能完全得到它。

0

這是我去:

seen = set() 
result = set() 
for s in map(set, [[1,2,3], [3,4,5], [5,6,7], [7,8,9]]): 
    result.update(s & seen) 
    seen.update(s) 
print result 

此打印:

set([3, 5, 7]) 
2

另一種簡單的解決方案(一行):

set.intersection(*[set(list) for list in list_of_lists]) 
+0

顯然是最好的答案,謝謝! – 2017-12-20 19:14:47