from itertools import zip_longest, groupby
okay = list(x == y for y, (x, _) in zip_longest(
(y for y in Y if y in X), groupby(x for x in X if x in Y)))
print(len(okay) >= 2 and all(okay))
Сначала мы отбрасываем ненужные элементы из обоих списков.Тогда мы можем использовать groupby
, чтобы свернуть последовательности тех же элементов X
.Например, ваш первый пример ['a', 'c', 'c', 'b', 'd', 'd', 'd']
сначала становится ['a', 'c', 'c', 'b'] (by discarding the unnecessary
'd' ), then
[('a', _), ('c', _), ('b', _)].Если мы сравниваем его ключи элемент за элементом с Y
без ненужных битов, а их по крайней мере 2, у нас есть совпадение.Если бы порядок был нарушен (например, ['b', 'c', 'c', 'a', 'd', 'd', 'd']
, было бы False
в okay
, и он потерпел бы неудачу. Если где-то появился дополнительный элемент, было бы сравнение с None
(благодаря zip_longest
) и снова False
был бы в okay
.
Это можно улучшить, используя наборы для ускорения поиска членства.