Python: return the index of the first element of a list which makes a passed function true

python list index
python find index of all occurrences in list
find index of element in list python
find index of duplicate elements in list, python
python 2d list find index
python find element in list
python find first occurrence in list
python find index in list of lists

The list.index(x) function returns the index in the list of the first item whose value is x.

Is there a function, list_func_index(), similar to the index() function that has a function, f(), as a parameter. The function, f() is run on every element, e, of the list until f(e) returns True. Then list_func_index() returns the index of e.


>>> def list_func_index(lst, func):
      for i in range(len(lst)):
        if func(lst[i]):
          return i
      raise ValueError('no element making func True')

>>> l = [8,10,4,5,7]
>>> def is_odd(x): return x % 2 != 0
>>> list_func_index(l,is_odd)

Is there a more elegant solution? (and a better name for the function)

You could do that in a one-liner using generators:

next(i for i,v in enumerate(l) if is_odd(v))

The nice thing about generators is that they only compute up to the requested amount. So requesting the first two indices is (almost) just as easy:

y = (i for i,v in enumerate(l) if is_odd(v))
x1 = next(y)
x2 = next(y)

Though, expect a StopIteration exception after the last index (that is how generators work). This is also convenient in your "take-first" approach, to know that no such value was found --- the list.index() function would throw ValueError here.

Python: How to find all indexes of an item in a List? –, So requesting the first two indices is (almost) just as easy: It's typical to refer a function like the one you describe as a "predicate"; it returns true or false for  In simple terms, the index() method finds the given element in a list and returns its position. If the same element is present more than once, the method returns the index of the first occurrence of the element. Note: Index in Python starts from 0, not 1.

@Paul's accepted answer is best, but here's a little lateral-thinking variant, mostly for amusement and instruction purposes...:

>>> class X(object):
...   def __init__(self, pred): self.pred = pred
...   def __eq__(self, other): return self.pred(other)
>>> l = [8,10,4,5,7]
>>> def is_odd(x): return x % 2 != 0
>>> l.index(X(is_odd))

essentially, X's purpose is to change the meaning of "equality" from the normal one to "satisfies this predicate", thereby allowing the use of predicates in all kinds of situations that are defined as checking for equality -- for example, it would also let you code, instead of if any(is_odd(x) for x in l):, the shorter if X(is_odd) in l:, and so forth.

Worth using? Not when a more explicit approach like that taken by @Paul is just as handy (especially when changed to use the new, shiny built-in next function rather than the older, less appropriate .next method, as I suggest in a comment to that answer), but there are other situations where it (or other variants of the idea "tweak the meaning of equality", and maybe other comparators and/or hashing) may be appropriate. Mostly, worth knowing about the idea, to avoid having to invent it from scratch one day;-).

9. Lists, Now let's find the index of the first occurrence of item 'Ok' in the list, all the occurrences of item 'Ok' in the list we will pass a lambda function to locate(), that will Returns the indexes of items in the list that returns True when passed Iterator vs Iterable vs Iteration · Make a class Iterable · Yield Keyword &  Python | Get first and last elements of a list. Sometimes, there might be a need to get the range between which a number lies in the list, for such applications we require to get the first and last element of the list. Let’s discuss certain ways to get the first and last element of the list.

One possibility is the built-in enumerate function:

def index_of_first(lst, pred):
    for i,v in enumerate(lst):
        if pred(v):
            return i
    return None

It's typical to refer a function like the one you describe as a "predicate"; it returns true or false for some question. That's why I call it pred in my example.

I also think it would be better form to return None, since that's the real answer to the question. The caller can choose to explode on None, if required.

11. Lists, The values that make up a list are called its elements. it would be disappointing if we couldn't assign list values to variables or pass lists as parameters to functions. Since pestilence is a member of the horsemen list, the in operator returns True. The first index selects the row, and the second index selects the column. Method #2 : Using filter() + lambda Using filter along with lambda can also help us to achieve this particular task, subscript index value 0 is used to specify that first element greater than value has to be taken.

Not one single function, but you can do it pretty easily:

>>> test = lambda c: c == 'x'
>>> data = ['a', 'b', 'c', 'x', 'y', 'z', 'x']
>>> map(test, data).index(True)

If you don't want to evaluate the entire list at once you can use itertools, but it's not as pretty:

>>> from itertools import imap, ifilter
>>> from operator import itemgetter
>>> test = lambda c: c == 'x'
>>> data = ['a', 'b', 'c', 'x', 'y', 'z']
>>> ifilter(itemgetter(1), enumerate(imap(test, data))).next()[0]

Just using a generator expression is probably more readable than itertools though.

Note in Python3, map and filter return lazy iterators and you can just use:

from operator import itemgetter
test = lambda c: c == 'x'
data = ['a', 'b', 'c', 'x', 'y', 'z']
next(filter(itemgetter(1), enumerate(map(test, data))))[0]  # 3

5. Data Structures, The values that make up a list are called its elements, or its items. The first example is a list of four integers. we can assign list values to variables or pass lists as parameters to functions: It is common to use a loop variable as a list index. The function len returns the length of a list, which is equal to the number of its  The original list is : [True, False, True, False, True, True, False] The list indices having True values are : [0, 2, 4, 5] Method #3 : Using itertools.compress() compress function checks for all the elements in list and returns the list of indices with True values.

you could do this with a list-comprehension:

l = [8,10,4,5,7]
filterl = [a for a in l if a % 2 != 0]

Then filterl will return all members of the list fulfilling the expression a % 2 != 0. I would say a more elegant method...

28.12. inspect — Inspect live objects, Return the index in the list of the first item whose value is x. The list methods make it very easy to use a list as a stack, where the last element added is a sequence consisting of those items from the sequence for which function(item) is true. More than one sequence may be passed; the function must then have as many  index of the first occurrence of x in s (at or after index i and before index j) share | improve this answer | follow | | | | answered Sep 17 '19 at 21:11

28.13. inspect — Inspect live objects, co_firstlineno, number of first line in Python source code Return all the members of an object in a list of (name, value) pairs sorted by name. Return true if the object is a built-in function or a bound built-in method. from inspect import signature >>> def foo(a, *, b:int, **kwargs): pass >>> sig = signature(foo) >>> str(sig)  Since the Python list follows the zero-based index rule, so the first index starts at 0. Hence, you can see that we passed ‘2’ as starting index as it contains the value ‘3’, which is included in the slice by default.

Python List, The inspect module provides several useful functions to help get information about code of a method, extract and format the argument list for a function, or get all the Return true if the object is a class, whether built-in or created in Python code. The first entry in the returned list represents frame; the last entry represents  WARNING: The expression works also with Python 2, but in the example is used range that returns an iterable object in Python 3 instead of a list like Python 2 (if you want to construct an iterable in Python 2 use xrange instead).

Python lists - working with lists in Python, Lists need not be homogeneous always which makes it a most powerful tool in Python. a definite sequence and the indexing of a list is done with 0 being the first index. Elements can be added to the List by using built-in append() function. of the List, index of the element is passed as an argument to the pop() method. In Python programming, a list is created by placing all the items (elements) inside a square bracket [ ], separated by commas. It can have any number of items and they may be of different types (integer, float, string etc.).

  • Will anybody ever start using the right 2.6/3.* idiom, that is, next(i for i, v in enumerate(L) if pred(v))?! It's shorter AND you can add a 2nd argument to get in lieu of a StopIteration. Ah well, +1 anyway since it's obviously more elegant and idiomatic than the coded-out loop even in this imperfect form.
  • This isn't obfuscatory - or at least, it's not any more obfuscatory than using map(f, seq) instead of [f(x) for x in seq] is. In other words, it's idiomatic. And like other idioms, it's not straightforward until it's part of your vocabulary.
  • just a reminder to catch StopIteration if the end condition might not be met.
  • Nice one! But what would we "name" X? Something like "Key" perhaps? Because it reminds me of l.sort(key=fn).
  • You could almost call it "Equals", so the line reads l.index(Equals(is_odd))
  • I think that what Alex (implicitly) suggested, Satisfies, is a good name for it.
  • @Robert, I do like Satisfies!
  • Sorry to be dense, but how do I express and use Satisfies in a generator that produces all the odd elements of list ref? (Haven't gotten the hang of generators yet, I guess ...) ref = [8,10,4,5,7] def is_odd(x): return x % 2 != 0 class Satisfies(object): def __init__(self, pred): self.pred = pred def __eq__(self, test_this): return self.pred(test_this) print ref.index( Satisfies(is_odd)) #>>>3
  • more elegant, better named, indeed
  • I think the OP wanted to emulate index's behavior of raising ValueError if the given value is not found.