在python中获取大多数列表的公共元素

时间:2018-01-21 23:17:23

标签: python

鉴于4个列表,我想获得3个或更多列表共有的元素。

a = [1, 2, 3, 4]
b = [1, 2, 3, 4, 5]
c = [1, 3, 4, 5, 6]
d = [1, 2, 6, 7]

因此,输出应为[1, 2, 3, 4]

我目前的代码如下。

result1 = set(a) & set(b) & set(c)
result2 = set(b) & set(c) & set(d)
result3 = set(c) & set(d) & set(a)
result4 = set(d) & set(a) & set(b)

final_result = list(result1)+list(result2)+list(result3)+list(result4)
print(set(final_result))

它工作正常,并提供所需的输出。但是,我有兴趣知道在Python中是否有一种简单的方法可以做到这一点,即:是否有内置函数?

4 个答案:

答案 0 :(得分:4)

使用Counter,您可以这样做:

代码:

a = [1, 2, 3, 4]
b = [1, 2, 3, 4, 5]
c = [1, 3, 4, 5, 6]
d = [1, 2, 6, 7]

from collections import Counter

counts = Counter(sum(([list(set(i)) for i in (a, b, c, d)]), []))
print(counts)

more_than_three = [i for i, c in counts.items() if c >= 3]
print(more_than_three)

结果:

Counter({1: 4, 2: 3, 3: 3, 4: 3, 5: 2, 6: 2, 7: 1})

[1, 2, 3, 4]

答案 1 :(得分:1)

迭代所有列表中的值以创建{value: number_of_lists_the_value_appears_in}的字典:

from collections import defaultdict

counts = defaultdict(int)
for list_ in (a, b, c, d):
    for value in set(list_):  # eliminate duplicate values with `set`
        counts[value] += 1

然后在第二步中使用count < 3删除所有值:

result = [value for value, count in counts.items() if count >= 3]

print(result)  # [1, 2, 3, 4]

答案 2 :(得分:0)

下面的代码将解决广义问题(使用n个列表,并且要求公共元素必须至少为k个)。它适用于不可清洗的物品,这是所有其他答案的主要缺点:

a = [1, 2, 3, 4]
b = [1, 2, 3, 4, 5]
c = [1, 2, 3, 4, 4, 5, 6]
d = [1, 2, 6, 7]


lists = [a, b, c, d]
result = []
desired_quanity = 3

for i in range(len(lists) - desired_quanity + 1):   #see point 1 below
    sublist = lists.pop(0)                          #see point 2
    for item in sublist:
        counter = 1   #1 not 0, by virute of the fact it is in sublist
        for comparisonlist in lists:
            if item in comparisonlist:
                counter += 1
                comparisonlist.remove(item)         #see point 3
        if counter >= desired_quanity:   
            result.append(item)

这样做的缺点是,对于每个列表中的每个元素,我们必须检查每个其他列表以查看它是否存在,但我们可以通过几种方式提高效率。同样的查找在列表中比在集合中慢很多(我们无法使用,因为OP在列表中有不可清除的项目),因此对于非常大的列表来说这可能会很慢。

1)如果我们要求一个项目在k列表中,我们不需要检查最后一个k-1列表中的每个项目,因为我们在搜索第一个k列表时已经选择了它。 / p>

2)一旦我们搜索了一个列表,我们就可以丢弃该列表,因为刚刚搜索到的列表中可能有助于我们最终结果的任何项目将再次被处理掉。这意味着每次迭代我们都会搜索更少的列表。

3)当我们检查一个项目是否在足够的列表中时,我们可以从列表中删除该项目,这意味着不仅随着我们的继续,列表的数量越来越短,列表本身越来越短,意味着更快查找。

作为一个后端,如果我们事先对原始列表进行了排序,这也可能有助于该算法有效地工作。

答案 3 :(得分:-2)

创建一个计数字典并过滤掉计数小于3的那些