Обратное совпадение с Python

Я пытался работать с двумя списками в Python 2.7. Я прошел часть пути, но потратив некоторое время на поиски, не сильно повлиял на результаты.

List1: Список последовательностей определенных номеров, которые я искал в List2. (например) ['209583', '185372', '684392', '995423']

List2: Имеет вариации этих чисел из списка1. (например) ['209583_345829', '57185372', '853921864']

Теперь я могу сопоставить и вытащить то, что нашел ниже... Но я также искал обратное; установить переменную для всех чисел в List1 которые не в List2,

matching = [s for s in list2 if any(xs in s for xs in list1)]

То, что следует оставить в несоответствующей переменной, будет '995423', Я пытался переработать код выше, но я чувствую, что он прямо у меня под носом.

Кроме того, не будет ли полезно просто использовать оператор If/Else по соображениям производительности? Например, если сопоставление делает это, иначе не сопоставление делает это... Таким образом, он выполняется только один раз против двух.

Это простой пример, но списки для обоих могут выдвинуть более 10000 строк на.

Спасибо!

2 ответа

Решение

Перво-наперво: список, который у вас под рукой, неверен. Чтобы создать полный список элементов в List1, у которых есть совпадения в List2, вы хотите использовать это:

Все элементы из списка List1 с совпадениями в списке List2

matches = [item for item in List1 if any(item in compared for compared in List2)]

Объяснить:
[s for s in List1 if any(xs in s for xs in List2)] - Ваш оригинальный алгоритм тянул элементы s от List1 и элементы xs от List2 и пытается увидеть, если xs содержался в s, что по своей сути является противоположностью того, что мы хотим сделать.

[s for s in list2 if any(xs in s for xs in list1)] - Ваш новый алгоритм инвертировал неправильные переменные. Сейчас тянет s от List2 а также xs от List1 и проверка, если xs в s - что ближе к оригинальной идее. Единственная проблема заключается в том, как ваш алгоритм настроен, он будет размещать элементы из List2 в список, если у них есть совпадение в List1 (что может быть, что вы хотите в конце концов?)

[item for item in List1 if any(item in compared for compared in List2)] - Сделан немного более подробным для легкого чтения, этот алгоритм будет извлекать элементы из List1 проверьте, есть ли у них "контейнер" в List2 и добавьте их в список, если они это сделают. (Примечание: альтернативное понимание списка, которое даст те же результаты, [item for item in List1 for compared in List2 if item in compared], который немного более интуитивно понятен для чтения.)

С этим из пути: если вы хотите получить каждый элемент из List1, который не имеет соответствия в List2, вы можете использовать алгоритм, который я указал выше, чтобы получить matches list, а затем, как сказал Али Саид Омар в комментарии, используйте операции set:

Все элементы в List1 БЕЗ совпадений в List2 - Операция Set

nomatches = set(List1) - set(matches)

Это займет все уникальные элементы List1, удалите соответствующие элементы и верните set объект со всеми несопоставленными элементами. В качестве альтернативы, если вы хотите решение в одном утверждении:

Все элементы в Списке 1 БЕЗ совпадений в Списке 2 - Понимание списка

nomatches = [item for item in List1 if not any(item in compared for compared in List2)]

Чтобы отдать должное, где кредит должен быть, это идентично решению yedpodtrzitko в комментариях поста.

Поскольку трудно сказать, что вы спрашиваете, и в комментариях вы хотя бы один раз перевернули то, что вы спрашиваете, я добавлю еще два алгоритма:

Все предметы в Списке2 С совпадают в Списке1

matches2 = [item for item in List2 for key in List1 if key in item]

Все элементы в списке List2 БЕЗ совпадений в списке List1 - понимание списка

nomatches2 = [item for item in List2 if not any(key in item for key in List1)]

Все элементы в List2 БЕЗ совпадений в List1 - Операция Set

nomatches2 = set(List2) - set(matches2)

Каждый из них был протестирован в вашем тестовом примере, описанном в вашем посте, и дал ожидаемые результаты. Если эти алгоритмы не делают то, что вам нужно, пожалуйста, еще раз проверьте, что это не проблема с вашей стороны, и если это не отвечает на ваш вопрос, пожалуйста, убедитесь, что вы понимаете, что вы спрашиваете, Благодарю.

Ваше "соответствие", как написано, дает значения из list2не из list1: ['209583_345829', '57185372']

Поэтому описанный подход не работает. Вам нужно переписать соответствие, чтобы оно возвращало элементы из list1, которые имеют некоторое соответствующее значение в list2.

Учитывая описание вашей проблемы, это должно работать:

non_match = [xs for xs in list1 if not any (xs in s for s in list2)]

Тем не менее, это возвращает ['684392', '995423'], Я не вижу 684392 в list2 в любом месте; Вы редактировали списки в какой-то момент, или вы ищете что-то в списке list2, содержащее все цифры элемента из list1, а не только сам элемент?

Другие вопросы по тегам