3

I have two lists in python list_A and list_B and I want to find the common item they share. My code to do so is the following:

both = []
for i in list_A:
    for j in list_B:
        if i == j:
            both.append(i)

The list common in the end contains the common items. However, I want also to return the indexes of those elements in the initial two lists. How can I do so?

Brown Bear
  • 19,655
  • 10
  • 58
  • 76
konstantin
  • 853
  • 4
  • 16
  • 50
  • 1
    What output do you expect? In general, I'd expect `for index, item in enumerate(something):` to help. – jonrsharpe Jul 04 '18 at 10:21
  • 3
    The index of which list you want ? Maybe use a [dictionnary](https://www.tutorialspoint.com/python/python_dictionary.htm) – Hearner Jul 04 '18 at 10:21
  • 1
    Question unclear. Do you want the indices, and if yes, of which list? Do you want the index of equal elements at the same index? Do you want the values instead of the indices as your code suggests? Please add a [MCVE]. – timgeb Jul 04 '18 at 10:23
  • 1
    Please provide example inputs (`list_A` and `list_B`) with matching output (`both`). Make sure you have more some elements that are duplicated twice or more at different positions so there's no ambiguity. – bruno desthuilliers Jul 04 '18 at 10:47

4 Answers4

8

It is advised in python that you avoid as much as possible to use for loops if better methods are available. You can efficiently find the common elements in the two lists by using python set as follows

both = set(list_A).intersection(list_B)

Then you can find the indices using the build-in index method

indices_A = [list_A.index(x) for x in both]
indices_B = [list_B.index(x) for x in both]
kosnik
  • 2,342
  • 10
  • 23
  • 2
    "It is advised in python that you avoid as much as possible to use for loops" => Definitly not. What is advised (and not only in Python) is to avoid writing inefficient code when there's a known efficient solution that isn't more (or much more) complicated to implement. – bruno desthuilliers Jul 04 '18 at 10:41
  • But since in Python `for` loops are always the least efficient way to do things, it is implied that we avoid them ;) – kosnik Jul 04 '18 at 10:48
  • Please re-read the last part of my comment: "when there's a known efficient solution that isn't more (or much more) complicated to implement." Not all uses of `for` loops can be _easily_ replaced by a _more efficient_ solution. Also keep readability / maintainability issues in mind. – bruno desthuilliers Jul 04 '18 at 10:52
  • "It is advised in python that you avoid as much as possible to use for loops." Seems like a generic statement that will easily be misunderstood by a lot of users. – Yoshikage Kira Apr 27 '21 at 23:19
  • what you really should have said it doing everything by brute force method is generally discouraged if there are better methods available. – Yoshikage Kira Apr 27 '21 at 23:46
  • Noted @Goion ! Edited accordingly – kosnik May 06 '21 at 08:40
  • A slight improvement, but still weird. I am not sure who told you the `for loop` is least efficient way to do things. It only tells part of the story. Hell even the `intersect` function uses `for loop` behind the scenes. https://stackoverflow.com/questions/20100003/whats-the-algorithm-of-set-intersection-in-python Also, technically speaking, for loop is the fastest way to iterate in python. This is because the iteration part is handled by C. Which is way faster than python. [Fasted way to loop in Python](https://www.youtube.com/watch?v=Qgevy75co8c) – Yoshikage Kira May 07 '21 at 02:21
  • This is quite inefficient because `index` takes time=length of the list. – user202729 Aug 17 '21 at 16:37
0

Instead of iterating through the list, access elements by index:

both = []
for i in range(len(list_A)):
    for j in range(len(list_B)):
        if list_A[i] == list_B[j]:
            both.append((i,j))

Here i and j will take integer values and you can check values in list_A and list_B by index.

RohithS98
  • 500
  • 2
  • 14
0

You can also get common elements and their indexes with numpy.intersect1d()

common_elements, a_indexes, b_indexes = np.intersect1d(a, b, return_indices=True)
0

It can easily be solved by using pandas.

import pandas as pd

to_match = pd.Series(["c", "a", "b", "b", "c", "a"])
unique_vals = pd.Series(["c", "b", "a"])
indices = pd.Index(unique_vals).get_indexer(to_match)

Out[1]: array([0, 2, 1, 1, 0, 2])
Alireza Ghaffari
  • 1,004
  • 3
  • 11
  • 24