3

I am comparing two lists in Python.

list1 is a superset of list2.

For the elements of list1, I want their index in list2 (if present).

Here are two examples.

list1 = ['a','b','c','d']
list2 = ['a','b']

The solution should produce [0, 1].

list1 = ['a','b','c','d']
list2 = ['b','a']

The solution should produce [1, 0].

I attempted the following code, but it only works for the first example.

list1 = ['a','b','c','d']
list2 = ['a','b']

pairwise = zip(list1,list2)
matched_index = [idx for idx, pair in enumerate(pairwise) if pair[0] == pair[1]]

This works. However, for the second set of sample data I get the wrong output [] instead of the expected output [1, 0].

list1 = ['a','b','c','d']
list2 = ['b','a']

pairwise = zip (list1,list2)
matched_index = [idx for idx, pair in enumerate(pairwise) if pair[0] == pair[1]]
print(matched_index) # prints []

Please suggest the way forward.

timgeb
  • 76,762
  • 20
  • 123
  • 145
Abhishek Kulkarni
  • 654
  • 1
  • 8
  • 20
  • 1
    I reopened this question because the accepted answer from the marked duplicate produces the wrong result for OP's second example. The dupe produces `[0, 1]`, but OP wants `[1, 0]`. – timgeb Dec 16 '18 at 11:56
  • 1
    In other words, OP wants to map the elements of `list1` to their indexes in `list2`. – timgeb Dec 16 '18 at 11:59
  • What's the expected result with `list2 = ['c','a']`? – iGian Dec 17 '18 at 06:23

3 Answers3

3

I suggest using a dictionary mapping the elements of list2 to their index - assuming list2 has unique elements.

>>> list1 = ['a','b','c','d']                                                                                            
>>> list2 = ['b','a']
>>> idx = {x:i for i,x in enumerate(list2)}                                                                            
>>> idx                                                                                                                
{'a': 1, 'b': 0}

Now you can issue

>>> [idx[x] for x in list1 if x in idx]                                                                                
[1, 0]
timgeb
  • 76,762
  • 20
  • 123
  • 145
2

Since list2 is a subset of list1, you can construct a dictionary mapping and then use dict.__getitem__ on values of list2 to extract indices:

list1 = ['a','b','c','d']
list2 = ['a','b']
list3 = ['b','a']

d = {v: k for k, v in enumerate(list1)}

res1 = list(map(d.__getitem__, list2))  # [0, 1]
res2 = list(map(d.__getitem__, list3))  # [1, 0]
jpp
  • 159,742
  • 34
  • 281
  • 339
  • @timgeb, Yup, but `d.get` is functionally not equivalent. Since `__getitem__` guarantees you'll get an error if a `list2` value is not in `list1`. – jpp Dec 16 '18 at 13:38
  • Can do: ```d = dict(enumerate(list1))```, i find it nicer – Aaron_ab Dec 16 '18 at 19:12
  • 2
    @Aaron_ab no, that creates an index:value mapping, we need value:index. – timgeb Dec 16 '18 at 20:52
  • @Aaron_ab, You would need `dict(map(reversed, enumerate(list1)))`. But I find the comprehension more readable. – jpp Dec 16 '18 at 23:14
0

Assuming there are unique elements in each list and len(list1) >= len(list2)

>>> list1 = ['a','b','c','d']                                                                                            
>>> list2 = ['d','a', 'f']
>>> print([list2.index(x) for x in list1 if x in list2])
shantanoo
  • 3,617
  • 1
  • 24
  • 37