Найти пересечение двух вложенных списков?
Я знаю, как получить пересечение двух плоских списков:
b1 = [1,2,3,4,5,9,11,15]b2 = [4,5,6,7,8]b3 = [val for val in b1 if val in b2]
или
def intersect(a, b): return list(set(a) & set(b)) print intersect(b1, b2)
Но когда мне нужно найти пересечение для вложенных списков, начинаются мои проблемы:
c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]
В итоге я хотел бы получить:
c3 = [[13,32],[7,13,28],[1,6]]
Ребята, вы можете мне помочь с этим?
Переведено автоматически
Ответ 1
Вам не нужно определять пересечение. Это уже первоклассная часть set .
>>> b1 = [1,2,3,4,5,9,11,15]>>> b2 = [4,5,6,7,8]>>> set(b1).intersection(b2)set([4, 5])
Ответ 2
Если вы хотите:
c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]c3 = [[13, 32], [7, 13, 28], [1,6]]
Тогда вот ваше решение для Python 2:
c3 = [filter(lambda x: x in c1, sublist) for sublist in c2]
В Python 3 filter возвращает итерацию вместо list, поэтому вам нужно обернуть filter вызовы с помощью list():
filter
list
list()
c3 = [list(filter(lambda x: x in c1, sublist)) for sublist in c2]
Объяснение:
Часть фильтра берет элемент каждого подсписка и проверяет, есть ли он в исходном списке c1. Понимание списка выполняется для каждого подсписка в c2.
Ответ 3
Для людей, которые просто хотят найти пересечение двух списков, запрашивающий предоставил два метода:
b1 = [1,2,3,4,5,9,11,15]b2 = [4,5,6,7,8]b3 = [val for val in b1 if val in b2]иdef intersect(a, b): return list(set(a) & set(b))print intersect(b1, b2)
и
def intersect(a, b): return list(set(a) & set(b))print intersect(b1, b2)
Но есть гибридный метод, который более эффективен, потому что вам нужно выполнить только одно преобразование между списком / набором, а не три:
b1 = [1,2,3,4,5]b2 = [3,4,5,6]s2 = set(b2)b3 = [val for val in b1 if val in s2]
Это будет выполняться за O (n), тогда как его оригинальный метод, включающий понимание списка, будет выполняться за O (n ^ 2)
Ответ 4
Функциональный подход:
input_list = [[1, 2, 3, 4, 5], [2, 3, 4, 5, 6], [3, 4, 5, 6, 7]]result = reduce(set.intersection, map(set, input_list))
и это может быть применено к более общему случаю 1+ списков