Reputation: 67
Just have a quick question about python. I was wondering if there was any simple pythonic way to take two list such as:
a = ['t', 'o', 'a', 'c']
b = ['c', 't', 'a', 'o']
and then return the common elements/chars that are also in the same order relative to each other between the two lists.
# possible outputs for this list could be either:
output: ['t', 'a']
output: ['t', 'o']
I can initially start with two lists and extract the matching elements while still keeping the order in tact by doing this:
c = ['z', 't', 'o', 'g', 'a', 'c', 'f']
d = ['e', 'q', 'c', 't', 'a', 'o', 'y']
a = [x for x in c if x in d]
b = [x for x in d if x in c]
Which will give me the original a and b lists. However, I wasn't able to find a away to reduce this further. Tried using sets but that doesn't keep the order of the elements. I know an easy way would probably just be brute for and n^2 to compare one list to another in place, but I am trying to avoid that and find a solution that would find the largest match in two lists relative to each other.
Upvotes: 1
Views: 756
Reputation: 377
>>> import itertools
>>> a = ['t', 'o', 'a', 'c']
>>> b = ['c', 't', 'a', 'o']
>>> [i for i in itertools.combinations(a, 2) if i in itertools.combinations(b, 2)]
[('t', 'o'), ('t', 'a')]
Edit:
To get all
>>> c = ['z', 't', 'o', 'x', 'a', 'c', 'f', 'g']
>>> d = ['e', 'q', 'c', 't', 'a', 'g', 'o', 'y']
>>> def f(l):
... r = []
... for i in range(2, len(l)+1):
... r += itertools.combinations(l, i)
... return r
>>>
>>> [i for i in f(c) if i in f(d)]
[('t', 'o'), ('t', 'a'), ('t', 'g'), ('a', 'g'), ('c', 'g'), ('t', 'a', 'g')]
Or:
>>> def f(l):
... return [j for i in range(2, len(l)+1) for j in list(itertools.combinations(l, i))]
>>>
>>> [i for i in f(c) if i in f(d)]
[('t', 'o'), ('t', 'a'), ('t', 'g'), ('a', 'g'), ('c', 'g'), ('t', 'a', 'g')]
Upvotes: 2