Мне нужно проверить, является ли список подмножеством другого - булево возвращение - это все, что я ищу.
Является ли тестирование равенства в меньшем списке после пересечения самым быстрым способом сделать это? Производительность имеет первостепенное значение, учитывая количество наборов данных, которые необходимо сравнить.
Добавление дополнительных фактов на основе обсуждений:
Будет ли один из списков одинаковым для многих тестов? Это как статическая таблица поиска.
Это должен быть список? Это не так - статическая таблица поиска может быть любой, которая работает лучше всего. Динамический - это диктовка, из которой мы извлекаем ключи для статического поиска.
Каково было бы оптимальное решение с учетом сценария?
Ответы:
Исполнительная функция Python обеспечивает это
set.issubset
. Однако у него есть несколько ограничений, из-за которых неясно, является ли это ответом на ваш вопрос.Список может содержать элементы несколько раз и имеет определенный порядок. Набор не делает. Кроме того, наборы работают только с хэшируемыми объектами.
Вы спрашиваете о подмножестве или подпоследовательности (что означает, что вам нужен алгоритм поиска строк)? Будет ли один из списков одинаковым для многих тестов? Какие типы данных содержатся в списке? И в этом отношении, это должен быть список?
Ваш другой пост пересекается с диктовкой и списком, прояснил типы и получил рекомендацию использовать ключевые словарные представления для их функциональности, подобной множеству. В этом случае было известно, что он работает, потому что словарные ключи ведут себя как набор (настолько, что до того, как у нас были наборы в Python, мы использовали словари). Интересно, как вопрос стал менее конкретным за три часа?
источник
источник
set(a).issubset(b)
потому что в этом случае вы конвертируете толькоa
в набор, но не такb
, что экономит время. Вы можете использоватьtimeit
для сравнения времени, потребляемого в двух командах. Например,timeit.repeat('set(a)<set(b)', 'a = [1,3,5]; b = [1,3,5,7]', number=1000)
иtimeit.repeat('set(a).issubset(b)', 'a = [1,3,5]; b = [1,3,5,7]', number=1000)
issubset
нужно сделать, это проверить, является ли аргументset
frozenset
set
set
символом / , а если нет, он преобразует его во временное для сравнения, запускает проверку, а затем выбрасывает временный , Различия по срокам (если таковые имеются) будут фактором небольших различий в затратах на поиск в LEGB (поискset
во второй раз обходится дороже, чем поиск по атрибутам в существующемset
), но это в основном промывка для достаточно больших входных данных.Объяснение: Генератор создает логические значения, просматривая список,
one
если этот элемент находится в спискеtwo
.all()
возвращается,True
если каждый элемент правдив, в противном случаеFalse
.Есть также преимущество, которое
all
возвращает False в первом случае отсутствующего элемента, а не обрабатывает каждый элемент.источник
set(one).issubset(set(two))
- это отличное решение. С решением, которое я разместил, вы сможете использовать его с любыми объектами, если у них определены правильные операторы сравнения.all
правильно закорачивать, второй будет выполнять все проверки, даже если из первой проверки будет ясно, что проверка не пройдёт. Просто бросьте квадратные скобки, чтобы получитьall(x in two for x in one)
.Предполагая, что элементы являются хэшируемыми
Если вам не нужны дубликаты, например.
[1, 2, 2]
а[1, 2]
затем просто используйте:.issubset
будет самый быстрый способ сделать это. Проверка длины перед тестированиемissubset
не улучшит скорость, потому что у вас все еще есть O (N + M) элементов для итерации и проверки.источник
Еще одним решением будет использование
intersection
.Пересечение множеств будет содержать
set one
(ИЛИ)
источник
Если list1 находится в списке 2:
(x in two for x in one)
генерирует списокTrue
.когда мы делаем,
set(x in two for x in one)
имеет только один элемент (True).источник
Теория множеств не подходит для списков, поскольку дубликаты приводят к неправильным ответам с использованием теории множеств.
Например:
не имеет смысла. Да, он дает ложный ответ, но это не правильно, поскольку теория множеств просто сравнивает: 1,3,5 против 1,3,4,5. Вы должны включить все дубликаты.
Вместо этого вы должны посчитать каждое вхождение каждого элемента и выполнить проверку больше чем равно. Это не очень дорого, потому что не использует O (N ^ 2) операций и не требует быстрой сортировки.
Затем, запустив это, вы получите:
источник
Поскольку никто не рассматривал сравнение двух строк, вот мое предложение.
Вы, конечно, можете проверить, не является ли труба («|») частью обоих списков, и, возможно, автоматически выбрали другой символ, но вы поняли идею.
Использование пустой строки в качестве разделителя не является решением, поскольку числа могут иметь несколько цифр ([12,3]! = [1,23])
источник
Простите, если я опаздываю на вечеринку. ;)
Чтобы проверить, является ли один
set A
из подмножествset B
,Python
имеетA.issubset(B)
иA <= B
. Он работаетset
только и отлично работает, НО сложность внутренней реализации неизвестна. Ссылка: https://docs.python.org/2/library/sets.html#set-objectsЯ придумал алгоритм для проверки
list A
подмножестваlist B
со следующими замечаниями.sort
сначала оба списка, прежде чем сравнивать элементы, чтобы претендовать на подмножество.break
loop
B[j]
A[i]
last_index_j
используется для началаloop
с того места,list B
где он остановился в последний раз. Это помогает избежать запуска сравнений с самого началаlist B
(что, как вы могли догадаться , ненужными, чтобы начатьlist B
сindex 0
в последующемiterations
.)Сложность будет
O(n ln n)
каждая для сортировки обоих списков иO(n)
для проверки подмножества.O(n ln n) + O(n ln n) + O(n) = O(n ln n)
,Код имеет много
print
утверждений, чтобы увидеть, что происходит на каждомiteration
изloop
. Они предназначены только для понимания.Проверьте, является ли один список подмножеством другого списка
Вывод
источник
Код ниже проверяет, является ли данный набор «правильным подмножеством» другого набора
источник
В Python 3.5 вы можете сделать,
[*set()][index]
чтобы получить элемент. Это гораздо более медленное решение, чем другие методы.или просто с лен и установить
источник
Вот как я знаю, если один список является подмножеством другого, последовательность имеет значение для меня в моем случае.
источник
Большинство решений считают, что списки не имеют дубликатов. Если в ваших списках есть дубликаты, вы можете попробовать это:
Это гарантирует, что подсписок никогда не имеет элементов, отличных от списка, или большего количества общего элемента.
источник
Если вы спрашиваете, содержится ли один список в другом списке, то:
Если вы спрашиваете, имеет ли каждый элемент в listA равное количество совпадающих элементов в listB, попробуйте:
источник
Если
a2 is subset of a1
тоLength of set(a1 + a2) == Length of set(a1)
источник