Given a list ["foo", "bar", "baz"] and an item in the list "bar", how do I get its index 1?
47 Answers
I find this two solution is better and I tried it by myself
>>> expences = [2200, 2350, 2600, 2130, 2190] >>> 2000 in expences False >>> expences.index(2200) 0 >>> expences.index(2350) 1 >>> index = expences.index(2350) >>> expences[index] 2350 >>> try: ... print(expences.index(2100)) ... except ValueError as e: ... print(e) ... 2100 is not in list >>> Comments
For those coming from another language like me, maybe with a simple loop it's easier to understand and use it:
mylist = [ "foo", "bar", "baz", "bar" ] for index, item in enumerate(mylist): if item == "bar": print(index, item) I am thankful for So what exactly does enumerate do?. That helped me to understand.
2 Comments
enumerate(mylist). That's why I cut that line and put enumerate function on loop. And it's better now. Remembering that all everything is an object in Python, but you can call enumerate as "built-in" function as official documentation does, of course. And, when I use enumerate to put a list in order, I continue having a list. Otherwise, you would need to call it a dictionary, which is not the case.1 Comment
As indicated by @TerryA, many answers discuss how to find one index.
more_itertools is a third-party library with tools to locate multiple indices within an iterable.
Given
import more_itertools as mit iterable = ["foo", "bar", "baz", "ham", "foo", "bar", "baz"] Code
Find indices of multiple observations:
list(mit.locate(iterable, lambda x: x == "bar")) # [1, 5] Test multiple items:
list(mit.locate(iterable, lambda x: x in {"bar", "ham"})) # [1, 3, 5] See also more options with more_itertools.locate. Install via > pip install more_itertools.
Comments
Let’s give the name lst to the list that you have. One can convert the list lst to a numpy array. And, then use numpy.where to get the index of the chosen item in the list. Following is the way in which you will implement it.
import numpy as np lst = ["foo", "bar", "baz"] #lst: : 'list' data type print np.where( np.array(lst) == 'bar')[0][0] >>> 1 1 Comment
Amazingly, next's fallback value second parameter mentioned in this comment in a duplicate thread hasn't been shown here yet.
The basic .index() works well when you can compare whole objects, but it's common to need to search a list of objects or dicts for a particular item by a certain property, in which case a generator with a condition is the natural choice:
>>> users = [{"id": 2, "name": "foo"}, {"id": 3, "name": "bar"}] >>> target_id = 2 >>> found_user = next(x for x in users if x["id"] == target_id) >>> found_user {'id': 2, 'name': 'foo'} This stops at the first matching element and is reasonably succinct.
However, if no matching element is found, a StopIteration error is raised, which is a little awkward to deal with. Luckily, next offers a second parameter next(gen, default) fallback to provide a more natural, except-free control flow:
>>> found_user = next((x for x in users if x["id"] == target_id), None) >>> if not found_user: ... print("user not found") ... user not found This is a bit more verbose, but still fairly readable.
If an index is desired:
>>> found_idx = next((i for i, x in enumerate(users) if x["id"] == 1), None) >>> found_idx None >>> next((i for i, x in enumerate(users) if x["id"] == 3), None) 1 As this comment points out, it may be best not to return the typical -1 for a missing index, since that's a valid index in Python. Raising is appropriate if None seems odd to return.
These are a bit verbose, but feel free to bury the code in a helper function if you're using it repeatedly, providing an arbitrary predicate.
>>> def find(it, pred): ... return next((x for x in it if pred(x)), None) ... >>> find(users, lambda user: user["id"] == 2) {'id': 2, 'name': 'foo'} >>> print(find(users, lambda user: user["id"] == 42)) None >>> find("foobAr", str.isupper) # works on any iterable! 'A' Comments
Use:
text = ["foo", "bar", "baz"] target = "bar" [index for index, value in enumerate(text) if value == target] For a small list of elements, this would work fine. However, if the list contains a large number of elements, it is better to apply a binary search with O(log n) runtime complexity.
1 Comment
using dictionary , where process the list first and then add the index to it
from collections import defaultdict index_dict = defaultdict(list) word_list = ['foo','bar','baz','bar','any', 'foo', 'much'] for word_index in range(len(word_list)) : index_dict[word_list[word_index]].append(word_index) word_index_to_find = 'foo' print(index_dict[word_index_to_find]) # output : [0, 5] Comments
A Pythonic way would to use enumerate, but you can also use indexOf from the operator module. Please note that this will raise ValueError if b not in a.
>>> from operator import indexOf >>> >>> help(indexOf) Help on built-in function indexOf in module _operator: indexOf(a, b, /) Return the first index of b in a. >>> indexOf(("foo", "bar", "baz"), "bar") # with tuple 1 >>> indexOf(["foo", "bar", "baz"], "bar") # with list 1 Comments
A function "indexof", similar to another languages that returns -1 if the element is not found, can be written like:
def indexof (obj, elem, offset=0): if elem in obj[offset:]: return offset + obj[offset:].index(elem) return -1 obj = ["foo", "bar", "baz", "foo"] print (indexof(obj, "not here")) print (indexof(obj, "baz")) print (indexof(obj, "foo", 1)) which returns
-1 2 3 Or an optimized version for big lists
def indexof (obj, elem, offset=0): if offset == 0: # No need for a sublist if elem in obj: return obj.index(elem) return -1 sublist = obj[offset:] if elem in sublist: return offset + sublist.index(elem) return -1 Comments
Certain structures in Python contains an index method that works beautifully to solve this question.
'oi tchau'.index('oi') # 0 ['oi','tchau'].index('oi') # 0 ('oi','tchau').index('oi') # 0 References:
1 Comment
Simple option:
a = ["foo", "bar", "baz"] [i for i in range(len(a)) if a[i].find("bar") != -1] 1 Comment
One can use zip() function to get the index of the value in the list. The code could be;
list1 = ["foo","bar","baz"] for index,value in zip(range(0,len(list1)),list1): if value == "bar": print(index) 2 Comments
zip(range(0,len(list1)),list1) is overkill when you could just do enumerate(list1)Don't. If you absolutely need to, use the .index(item...) method on list. However, it takes linear time, and if you find yourself reaching for it, you are probably misusing lists to do something you should not do with them.
Most likely, you care either about 1) a two-way mapping between integers and items, or 2) about finding an item in a sorted list of items.
For the first one, use a pair of dictionaries. If you want a library that does this for you, use the bidict library.
For the second one, use methods that can properly make use of the fact that the list is sorted. Use the built-in bisect module in python.
If you find yourself wanting to insert items in a sorted list, you should also not use a sorted list. Either weaken the sorted requirement to a heap using the builtin heapq module, or use the sortedcontainers library.
It is bad practice to use a data structure that is not designed for what you want to do. Using one that matches the task you give it will both telegraph to the reader that you want to do that specific thing, and also make your solution a lot faster/more scalable in practice.
Comments
A simple solution in Python:
li1 = ["foo", "bar", "baz"] for i in range(len(li1)): if li1[i] == "bar": print(i) The data type of the list elements is irrelevant. Just replace the "bar" with the element you are looking for. We can also write a function for this as:
def indexfinder(element,lis): for i in range(len(lis)): if lis[i] == element: return i Comments
Here are different methods to find all occurrences of "bar" in a list, I have ranked by execution speed and usecase:
lst = ["foo", "bar", "baz"] item = "bar" itertools.compress (Fastest: ~0.026 s) Memory Efficient
from itertools import compress indices = list(compress(range(len(lst)), [val == item for val in lst])) List Comprehension (~0.018 s) readability and simplicity
indices = [i for i, v in enumerate(lst) if v == item] collections.deque (~0.053 s) Faster Append
from collections import deque indices = deque() for i, val in enumerate(lst): if val == item: indices.append(i) indices = list(indices) filter + lambda (~0.029 s) Functional Approach
indices = list(filter(lambda i: lst[i] == item, range(len(lst)))) NumPy (np.where) (~0.165 s) Faster for Large Lists
import numpy as np indices = np.where(np.array(lst) == item)[0].tolist() Pandas (pd.Series.index) (~9.475 s) Best for DataFrames & Large Datasets
import pandas as pd indices = pd.Series(lst).index[pd.Series(lst) == item].tolist() Output:
[1] 5 Comments
timeit module and run it multiple times (e.g., 100,000 iterations to ensure meaningful benchmarking.) and compute the average execution time (Approximate). ex: import timeit timeit.timeit('code', setup='import_libraries', number=100000)
"bar", [2] All the indices of"bar"?