-2

I want to find intersection of two lists with original order. So if

a = [2, 3, 5, 6]
b = [17, 28, 2, 8, 0, 3]

I need [2, 3]. But for [3, 2, 5, 6] and [17, 28, 2, 8, 0, 3] I need [2].

How I can get it?

jevik
  • 43
  • 4
  • 2
    What does it mean to "keep order"? E.g. if you have `a = [2,3]` and `b=[3,2]`? Is the order of `a` always the one that is relevant? If yes, you could simply loop over `a` and keep only those values that are in `b` – lucidbrot Aug 04 '20 at 12:40
  • 3
    Does this answer your question? [Ordered intersection of two lists in Python](https://stackoverflow.com/questions/23529001/ordered-intersection-of-two-lists-in-python) – lucidbrot Aug 04 '20 at 12:41
  • @lucidbrot If I delete all other numbers from `a` and `b` (except their intersection), I want to get the same order in `a` and `b` – jevik Aug 04 '20 at 12:45
  • 2
    Why expect `[2]`, not `[3]`? – superb rain Aug 04 '20 at 12:48
  • 2
    your question is unclear. Please indicate what to do with duplicate elements, and with elements that are found in different orders between the two lists. – Pierre D Aug 04 '20 at 12:50
  • 2
    Welcome to Stack Overflow. Please take the [tour](https://stackoverflow.com/tour), read about [what's on-topic](https://stackoverflow.com/help/on-topic), and read [How to Ask a Good Question](https://stackoverflow.com/help/how-to-ask). – Ivo Mori Aug 04 '20 at 12:51
  • @jevik So what you want to do is to take `a[0]` iff it is in `b`, then take `a[1]` iff it is in `b` after the index where `a[0]` was in `b` and so on? – lucidbrot Aug 04 '20 at 12:55
  • > indicate what to do with duplicate elements `a` and `b` can be set > with elements that are found in different orders between the two lists I need to get only numbers that is in `a` and `b` with same order, but it is allowed to some numbers (maybe no one) between them. So for `2, 3` and `3, 2` I need to get only `2` @lucidbrot YES – jevik Aug 04 '20 at 12:57
  • 1
    I think the question is to find the [longest common subsequence](https://en.wikipedia.org/wiki/Longest_common_subsequence_problem), which is a classic problem in computer science. A bit beyond the scope of a SO question, though... – Jiří Baum Aug 04 '20 at 13:14
  • 1
    what is the expected result for `a = [0, 1, 2, 3, 4, 5]` and `b = [4, 1, 2, 3, 5, 0]`? If it is just `[0]` or `[4, 5]`, then it is simple. If you want the longest common subsequence, as surmised by @sabik, then it is NP-hard (but has some decent heuristic approximate solutions). – Pierre D Aug 04 '20 at 13:23
  • Also, if it's a uni assignment, the expected algorithm will be in the lectures; if it's an interview assignment, the "correct" answer will be whichever approach is taught at the university attended by the interviewer... – Jiří Baum Aug 05 '20 at 11:53

5 Answers5

2
def inter(a,b):
    c = []
    for num in a:
        if num in b and (not len(c) or b.index(c[-1]) < b.index(num)):
            c.append(num)
    return c
1

You will have to loop over one list, searching the element in the other list, and only search the other list from that point for any following element.

Code could be:

a = [3, 2, 5, 6]
b = [17, 28, 2, 8, 0, 3]

def intersect(a,b):
    result = []
    ix = 0
    for x in a:
        try:
            ix = b[ix:].index(x)
            result.append(x)
        except ValueError:
            pass
    return result

print(intersect(a, b))

It gives:

[3]

NB: if you want [2], just use intersect(b, a)

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
  • For `7 8 6 6 8 10 3 3` and `7 4 10 8 7` it will give `[7]`. I need to get `7 8` or `7 10` -- more important that order of result was the same in `a` and `b`, allowing some (may be 0) elements was between result items in original lists – jevik Aug 04 '20 at 13:04
  • @jevik There was an indentation error... Fixed. It now returns `[7, 10]`. – Serge Ballesta Aug 04 '20 at 13:11
1

This is more of a research problem than a StackOverflow question...

The phrase to search for is "longest common subsequence problem". Once you've found an algorithm that suits your situation, it will probably be clearer how to translate it into Python, or you can ask more targeted questions here.

Jiří Baum
  • 6,697
  • 2
  • 17
  • 17
  • PS: If it's a uni assignment, the expected algorithm will be in the lectures; if it's an interview assignment, the "correct" answer will be whichever approach is taught at the university attended by the interviewer... – Jiří Baum Aug 06 '20 at 23:45
1
a = [7, 8, 6, 6, 8, 10, 3, 3]
b = [7, 4, 10, 8, 7]

def magic(a, b):
    result = []

    # early abort
    if len(a) == 0 or len(b) == 0:
        return result

    try:
        index_b = b.index(a[0])
        result.append(b[index_b])
        # a[0] was found in b at index index_b. Disregard any items before index_b in the future.
        # And since we found a[0], we can remove it from our search list a.
        # continue with next search
        return result + magic(a[1:], b[index_b+1:])
        
    except ValueError:
        # a[0] is not in b. continue with next item in a.
        # No need for new code, just do the same function again for a shorter a.
        return result + magic(a[1:], b)

print(magic(a,b))

This prints [7,8]. I hope the code is self-explanatory.

It fulfills your test case 1:

a = [2, 3, 5, 6]
b = [17, 28, 2, 8, 0, 3]

# prints [2, 3]

It does not fulfill your test case 2:

>>> a = [3, 2, 5, 6]
>>> b = [17, 28, 2, 8, 0, 3]
>>> tmp.magic(a,b)
[3]
# you wanted [2]

But it does follow my earlier comment (to which you said "YES")

@jevik So what you want to do is to take a[0] iff it is in b, then take a[1] iff it is in b after the index where a[0] was in b and so on? – lucidbrot 41 mins ago

Your test case 3 from a comment:

For a=7 8 6 6 8 10 3 3 and b=7 4 10 8 7 with your solve I get 7 8 10. I need to get 7 8

My program does print [7,8] for that.

lucidbrot
  • 5,378
  • 3
  • 39
  • 68
-1

You can use & operation between two sets, that will give you an intersection set without change in order

a = [2, 3, 5, 6]
b = [17, 28, 2, 8, 0, 3]

intersection = list(set(a) & set(b))
print(intersection)
Dinesh
  • 812
  • 4
  • 14
  • No. For `a=7 8 6 6 8 10 3 3` and `b=7 4 10 8 7` with your solve I get `7 8 10`. I need to get `7 8` – jevik Aug 04 '20 at 12:48
  • 1
    "[3, 2, 5, 6] and [17, 28, 2, 8, 0, 3] I need [2]", I don't understand this. Can you elaborate on it. – Dinesh Aug 04 '20 at 12:54