Я знаю, как получить пересечение двух плоских списков:
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]]
Ребята, можете ли вы помочь мне с этим?
связанные с
python
list
intersection
elfuego1
источник
источник
Ответы:
Если хочешь:
Тогда вот ваше решение для Python 2:
В Python 3
filter
возвращается итерируемый вместоlist
, так что вам нужно обернутьfilter
вызовы сlist()
:Объяснение:
Часть фильтра берет элемент каждого подсписка и проверяет, находится ли он в исходном списке c1. Понимание списка выполняется для каждого подсписка в c2.
источник
filter(set(c1).__contains__, sublist)
для эффективности. Кстати, преимущество этого решения заключается в том, что онfilter()
сохраняет типы строк и кортежей.c3 = [[x for x in sublist if x in c1] for sublist in c2]
Вам не нужно определять пересечение. Это уже первоклассная часть сета.
источник
set(b1) & set(b2)
? ИМО его чище использовать оператором.set
приведет к тому, что код будет на порядок быстрее. Вот пример теста Bench®Для людей, которые просто хотят найти пересечение двух списков, Аскер предоставил два метода:
Но есть гибридный метод, который более эффективен, потому что вам нужно сделать только одно преобразование между списком / множеством, а не три:
Это будет работать в O (n), тогда как его оригинальный метод, включающий понимание списка, будет работать в O (n ^ 2)
источник
Функциональный подход:
и это может быть применено к более общему случаю списков 1+
источник
set(*input_list[:1]).intersection(*input_list[1:])
. Версия итератора (it = iter(input_list)
):reduce(set.intersection, it, set(next(it, [])))
. Обе версии не требуют преобразования всех входных списков для установки. Последнее более эффективно использует память.from functools import reduce
для использования в Python 3. Или еще лучше, используйте явныйfor
цикл.Версия для понимания чистого списка
Свести вариант:
Вложенный вариант:
источник
Оператор & принимает пересечение двух множеств.
источник
Питонический способ пересечения двух списков:
источник
Вы должны сгладить, используя этот код (взят из http://kogs-www.informatik.uni-hamburg.de/~meine/python_tricks ), код не проверен, но я уверен, что он работает:
После того, как вы сгладили список, вы выполняете пересечение обычным способом:
источник
Поскольку
intersect
был определен, достаточно базового понимания списка:Улучшение благодаря замечанию С. Лотта и связанному замечанию ТМ:
источник
Данный:
Я считаю, что следующий код работает хорошо и, возможно, более кратко, если использовать операцию set:
Получилось:
Если заказ необходим:
у нас есть:
Кстати, для более стиля Python, этот тоже хорошо:
источник
Я не знаю, опоздал ли я на ваш вопрос. После прочтения вашего вопроса я придумал функцию intersect (), которая может работать как со списком, так и с вложенным списком. Я использовал рекурсию, чтобы определить эту функцию, она очень интуитивно понятна. Надеюсь, это то, что вы ищете:
Пример:
источник
Считаете ли вы,
[1,2]
чтобы пересечь с[1, [2]]
? То есть вас интересуют только числа или структура списка?Если только цифры, исследуйте, как «сгладить» списки, затем используйте
set()
метод.источник
Я также искал способ сделать это, и в итоге все закончилось так:
источник
источник
Мы можем использовать методы set для этого:
источник
Чтобы определить пересечение, которое правильно учитывает количество элементов, используйте
Counter
:источник
Вот один из способов установки
c3
, который не включает наборы:Но если вы предпочитаете использовать только одну строку, вы можете сделать это:
Это понимание списка в понимании списка, что немного необычно, но я думаю, что вам не должно быть особых проблем с этим.
источник
Для меня это очень элегантный и быстрый способ к ней :)
источник
Плоский список может быть
reduce
легко сделан .Все что вам нужно использовать инициализатор - третий аргумент в
reduce
функции.Приведенный выше код работает как для python2, так и для python3, но вам необходимо импортировать модуль Reduce as
from functools import reduce
. См. Ссылку ниже для деталей.для python2
для python3
источник
Простой способ найти разницу и пересечение между итерациями
Используйте этот метод, если повторение имеет значение
источник