226

What is a good way to find the index of an element in a list in Python?
Note that the list may not be sorted.

Is there a way to specify what comparison operator to use?

Benyamin Jafari
  • 27,880
  • 26
  • 135
  • 150
Himadri Choudhury
  • 10,217
  • 6
  • 39
  • 47
  • 2
    Can unmark this one as duplicated, the questions and answers don't handle the case of class instances that match a criteria. – Caveman Jun 22 '20 at 16:15
  • Also finding the index of an item in a list is not the same thing as finding the item in a list. – mikemaccana Feb 05 '21 at 14:28

10 Answers10

313

From Dive Into Python:

>>> li
['a', 'b', 'new', 'mpilgrim', 'z', 'example', 'new', 'two', 'elements']
>>> li.index("example")
5
stivlo
  • 83,644
  • 31
  • 142
  • 199
Matt Howell
  • 15,750
  • 7
  • 49
  • 56
  • 19
    But this code gives error when element is not in the list.In current example context if I search for 'three' (i.e: li.index('three')) gives error. – Kedar.Aitawdekar May 28 '14 at 07:31
  • 12
    You can catch the error to detect when something isn't in the list. `try: li.index("three") except ValueError: found = false` – Peter G Nov 18 '16 at 16:06
  • 2
    if you really want to find the index then, first check element in array if True then only do => li.index("example") – yogesh mhetre Dec 04 '19 at 12:37
176

If you just want to find out if an element is contained in the list or not:

>>> li
['a', 'b', 'new', 'mpilgrim', 'z', 'example', 'new', 'two', 'elements']
>>> 'example' in li
True
>>> 'damn' in li
False
Eduardo
  • 1,791
  • 1
  • 11
  • 5
72

The best way is probably to use the list method .index.

For the objects in the list, you can do something like:

def __eq__(self, other):
    return self.Value == other.Value

with any special processing you need.

You can also use a for/in statement with enumerate(arr)

Example of finding the index of an item that has value > 100.

for index, item in enumerate(arr):
    if item > 100:
        return index, item

Source

tedder42
  • 23,519
  • 13
  • 86
  • 102
Brian R. Bondy
  • 339,232
  • 124
  • 596
  • 636
61

Here is another way using list comprehension (some people might find it debatable). It is very approachable for simple tests, e.g. comparisons on object attributes (which I need a lot):

el = [x for x in mylist if x.attr == "foo"][0]

Of course this assumes the existence (and, actually, uniqueness) of a suitable element in the list.

ThomasH
  • 22,276
  • 13
  • 61
  • 62
  • 10
    `el = [x for x in mylist if x.attr == "foo"]` `if el: do something with el[0]` solves the "existence" problem – berkus Jul 30 '15 at 16:33
  • 15
    `el = next((x for x in mylist if x.attr == "foo"), None)` if you want to receive a value even when doesn't exist – Thiago Lages de Alencar Feb 08 '21 at 12:13
  • 2
    `[*[label_set for label_set in prediction_label_sets if x == 3], None][0]` If you want it to fallback to none, without using an iterator. Not sure if it's simpler or harder. – Sebastian Jan 26 '22 at 09:47
19

assuming you want to find a value in a numpy array, I guess something like this might work:

Numpy.where(arr=="value")[0]
Jorgesys
  • 124,308
  • 23
  • 334
  • 268
  • 1
    doesn't work for multidimensional arrays if you're looking for a specific row, e.g. `arr = np.array([[0,0,1],[0,1,0],[1,0,0]])` if you do `np.where(arr == [0,1,0])` it doesn't give the right result – ierdna Aug 21 '18 at 22:11
  • @ierdna, don't you need to supply `axis=0` or `axis=1`? – mLstudent33 Sep 28 '19 at 08:17
8

There is the index method, i = array.index(value), but I don't think you can specify a custom comparison operator. It wouldn't be hard to write your own function to do so, though:

def custom_index(array, compare_function):
    for i, v in enumerate(array):
        if compare_function(v):
            return i
David Z
  • 128,184
  • 27
  • 255
  • 279
6

I use function for returning index for the matching element (Python 2.6):

def index(l, f):
     return next((i for i in xrange(len(l)) if f(l[i])), None)

Then use it via lambda function for retrieving needed element by any required equation e.g. by using element name.

element = mylist[index(mylist, lambda item: item["name"] == "my name")]

If i need to use it in several places in my code i just define specific find function e.g. for finding element by name:

def find_name(l, name):
     return l[index(l, lambda item: item["name"] == name)]

And then it is quite easy and readable:

element = find_name(mylist,"my name")
jki
  • 4,617
  • 1
  • 34
  • 29
4

The index method of a list will do this for you. If you want to guarantee order, sort the list first using sorted(). Sorted accepts a cmp or key parameter to dictate how the sorting will happen:

a = [5, 4, 3]
print sorted(a).index(5)

Or:

a = ['one', 'aardvark', 'a']
print sorted(a, key=len).index('a')
Jarret Hardie
  • 95,172
  • 10
  • 132
  • 126
3

I found this by adapting some tutos. Thanks to google, and to all of you ;)

def findall(L, test):
    i=0
    indices = []
    while(True):
        try:
            # next value in list passing the test
            nextvalue = filter(test, L[i:])[0]

            # add index of this value in the index list,
            # by searching the value in L[i:] 
            indices.append(L.index(nextvalue, i))

            # iterate i, that is the next index from where to search
            i=indices[-1]+1
        #when there is no further "good value", filter returns [],
        # hence there is an out of range exeption
        except IndexError:
            return indices

A very simple use:

a = [0,0,2,1]
ind = findall(a, lambda x:x>0))

[2, 3]

P.S. scuse my english

Gael
  • 47
  • 1
2

how's this one?

def global_index(lst, test):
    return ( pair[0] for pair in zip(range(len(lst)), lst) if test(pair[1]) )

Usage:

>>> global_index([1, 2, 3, 4, 5, 6], lambda x: x>3)
<generator object <genexpr> at ...>
>>> list(_)
[3, 4, 5]
SingleNegationElimination
  • 151,563
  • 33
  • 264
  • 304