Предполагая, что порядок элементов в выходных данных не имеет значения ...
Конвертируйте каждый список в набор, затем запустите set.intersection
для них. Вы можете использовать понимание списка и расширение аргумента, чтобы сделать это в одной строке:
list1 = [1,2,3,4,5]
list2 = [2,3,4,5,6]
list3 = [3,4,5,6,7]
listoflists = [list1,list2,list3]
commons = list(set.intersection(*[set(l) for l in listoflists]))
print (commons)
[3, 4, 5]
Для большей эффективности вы можете вызвать пересечение по отдельности:
list1 = [1,2,3,4,5]
list2 = [2,3,4,5,6]
list3 = [3,4,5,6,7]
listoflists = [list1,list2,list3]
commons = set(listoflists[0])
if (len(listoflists)>1):
for l in listoflists[1:]:
commons = commons.intersection(l)
Для меня это было более подходящее время с длинными списками, которые не нужно искать полностью. Определенно, здесь есть место для улучшения:
import timeit
setups = """
list1 = [1,2]
list2 = [3,4]
list3 = list(range(5000))
list3 = list(range(5001))
list4 = list(range(20000))
listoflists1 = [list1,list2,list3]
listoflists2 = [list1,list2,list3,list4]
"""
test2= """
commons = set(listoflists2[0])
for l in listoflists2[1:]:
commons = commons.intersection(l)
"""
result = timeit.timeit(setup=setups, number=5000, stmt="list(set.intersection(*(set(l) for l in listoflists1)))")
print("one liner with small exclusive lists and one large: %s" % result)
result = timeit.timeit(setup=setups, number=5000, stmt=test2)
print("loop with more large lists: %s" % result)
result = timeit.timeit(setup=setups, number=5000, stmt="list(set.intersection(*(set(l) for l in listoflists2)))")
print("one liner with more large lists: %s" % result)
one liner with small exclusive lists and one large: 0.8411386758089066
loop with more large lists: 2.130048044025898
one liner with more large lists: 4.127526797354221