Поиск пересечения списков с помощью фрагментов списка Python и рекурсии

#python #recursion #slice

#python #рекурсия #фрагмент

Вопрос:

 def findIntersection(list1, list2):
    if list1 == [] or list2 == []:
        return []
    elif list1[0] < list2[0]:
        return [list1[0]]   findIntersection(list[1:], list2)
    elif list1[0] > list2[0]:
        return [list2[0]]   findIntersection(list1, list2[1:])
    else:
        return ([list1[0]]   findIntersection(list1[1:], list2[1:])) 
  

Это код, который я написал до сих пор, и конечная цель — найти пересечение двух списков. Так, например, findIntersection([1,2,4], [0,2,3]) == [2] или найти пересечение([0,2,3,5], [1,2,4,5,6]) == [2,5].

С чего мне начать и что я делаю не так. Также было бы полезно получить более подробное объяснение фрагментов python. Спасибо.

Ответ №1:

Ваша проблема в том, что вы тщательно возвращаете элементы, которых нет в пересечении:

 elif list1[0] < list2[0]:
    return [list1[0]]   findIntersection(list[1:], list2)
elif list1[0] > list2[0]:
    return [list2[0]]   findIntersection(list1, list2[1:])
else:
    return ([list1[0]]   findIntersection(list1[1:], list2[1:]))
  

Из этих трех случаев единственный, который идентифицирует допустимый элемент пересечения, является последним: элемент находится в обоих списках.

Для двух других ваша рекурсия верна, но добавление нижнего элемента является ошибкой. Вы должны отказаться от этого элемента, потому что вы знаете, что его нет в обоих списках.

 elif list1[0] < list2[0]:
    # Drop the lowest element of list1 and recur
    return findIntersection(list[1:], list2)
elif list1[0] > list2[0]:
    # Drop the lowest element of list2 and recur
    return findIntersection(list1, list2[1:])
else:
    The element is in both lists; add it to the solution and recur.
    return ([list1[0]]   findIntersection(list1[1:], list2[1:]))
  

Ответ №2:

[i for i in list1 if i in list2]

Использует понимание списка. Циклически перебирает каждый элемент в списке1 и добавляет их в новый список тогда и только тогда, когда они найдены в списке2.

Если вы хотите использовать срезы и рекурсию, то вы очень близки… вы хотите включить элемент в список пересечений, только если он находится в обоих списках — это верно только в финале else . Также у вас есть опечатка в вашем коде — list где должно быть list1 . Также обратите внимание, что этот метод требует сортировки входных списков (либо по возрастанию, либо по убыванию).

 def findIntersection(list1, list2):
    if list1 == [] or list2 == []:
        return []
    elif list1[0] < list2[0]:
        return findIntersection(list1[1:], list2)
    elif list1[0] > list2[0]:
        return findIntersection(list1, list2[1:])
    else:
        return [list1[0]]   findIntersection(list1[1:], list2[1:])

list1 = [0,2,3,5]
list2 = [1,2,3,4,5,6]
print(findIntersection(list1, list2))
  

ВОЗВРАТ [2,3,5]

Комментарии:

1. Это эффективный ответ, однако я пытаюсь использовать нарезку / рекурсию Python, чтобы я мог лучше понять концепцию.

2. Ах. Извините, что пропустил это. Если я понимаю концепцию того, как вы пытаетесь это сделать, тогда ваши списки сначала нужно отсортировать в порядке возрастания?

3. Правильно. Итак, в нескольких тестовых примерах, которые я использую, я просматриваю списки, которые уже установлены в порядке возрастания.

4. Спасибо за этот ответ. Я не могу поверить, что не видел такой очевидной ошибки в своем коде. Как бы вы объяснили концепцию нарезки Python в ее простейшей форме? Я считаю, что это разделение списка на first и rest, но какие преимущества это дает?